Pull to refresh

Comments 542

Этот код прекрасно иллюстрирует гипотезу. Он был написан так же, как мы привыкли решать примеры. Масса промежуточных шагов удерживалась непосредственно в голове, а «на бумагу» попало лишь окончательное решение. 150 строк, которые решают всю чёртову задачу одним махом. Этот код явно был написан очень талантливым парнем!

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

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

Только вот чтобы сначала написать 1500 строк, нужно их всё таки все держать в памяти. А во вторых, рефакторинг 1500 строк до 10 раз по 150 — это не очень хороший рефакторинг. Надо тогда уж хотя бы до 100 раз по 15.

Логичнее писать псевдокод, его оптимизировать, а потом уже реализовывать (и еще раз оптимизировать). Сам псевдокод можно оставить в комментарии к исходнику.

1500 строк псевдокода — хотелось бы посмотреть :)
Любую книгу по алгоритмам откройте.
Хотя современным «программистам» зачем оно…

… И вы там не найдете такого псевдокода:)
Алгоритмы обычно более короткие.

Распишите-ка алгоритм, например, работы банкомата с картой.

А такого вы и не увидите в книгах по алгоритмам.
Вы можете увидеть псевдокод RSA, можете увидеть декартово дерево. Но до 1500 строк там очень далеко:)

Нельзя на псевдокоде писать алгоритмы. Одна из проблем псевдокода — отсутствие спецификации.
Простой пример — двойное отрицание над int в С++.
Двойное отрицание дает нам приведение к строгому bool.
Но в псевдокоде что даст двойное отрицание? Это будет логическая операция или бинарная? Конкретно в случае двойного отрицания понятно, что оно бессмысленно в случае бинарной операции. Но в любом случае однозначности нет.

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

Большинство нынешних «разработчиков» это и есть машина для исполнения псевдокода. Причем, очень некачественная.

PS и да, если вы не можете написать свои сишные уродцы типа «двойного отрицания над int» русским языком, то ваш код сразу можно выкинуть в помойку. Только там место недокументированному коду. Такому коду нельзя доверять, пока его сам не проверишь целиком. А, значит, проще написать заново.

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

А потом у нас у всех хартблид или иные факапы сходного масштаба

то, что тут написано, и есть псевдокод.
в чем проблема написать «строгий boolean»?

А почему "троечник" не может решить пример в три действия?


(lnx/x^2)' = (lnx)'/x^2 + lnx * (x^-2)' = 1/x / x^2 -2 * lnx / x^3=(1-2*lnx)/x^3

И не связана ли возможность "отличника" быстро щелкать примеры с тем
что он в десятки, а возможно и в сотни раз больше задачек решил, чем троечник (
который например банально не делает домашнее задание) и тем самым просто натренировался как "собака Павлова"?

Ну, в три действия — это уже «хорошист»!

Безусловно, бывают такие талантливые троечники, которым просто на математику наплевать, потому что у них есть куда более интересные для них занятия: литература, плавание и КВН, например. На таких ведь так мало…

А почему мало? У меня один одноклассник троечник — руководитель в строительной компании, второй — бизнесмен в области холодильного оборудования (мерседес новенький купил только только закончив универ). У отличников, тоже все нормально, но троечник это не приговор. Отличники часто чсв свое применить в жизни не могут.

Тут дело не в количестве действий. В решении apro не записано самое важное:
(lnx/x^2)' = (lnx * x^-2)'
Это и есть «отличие» — увидеть возможность упростить задачу ещё до применения стандартных правил. А способность в уме выполнять последовательность действий, которую записал «троечник» — тоже, конечно, «отличие», но уже другое.
А смысл упрощать её до такого вида, если делением намного проще получается и быстрее?
Но здесь нет никакого «отличия» — как сказали выше, просто заученный алгоритм и всё
Это примерно как 36*98 можно считать в лоб столбиком, а можно 36*(100-2)=3600-36*2=3600-72=3528. Мне быстрее вторым способом.
Вы не поняли меня. Безусловно, в вашем случае я считал бы точно так же.
Я же говорил точно про тот пример, считать производную как производную частного там намного проще и быстрее, так зачем использовать «другой» метод, если можно пойти по классике?
Формулу (a/b)'=(a'b-ab')/b^2 должны знать и отличник, и троечник. Её использование и стандартно (т.е. более узнаваемо и понятно), и более элегантно. А чтобы её вспомнить, то можно «на полях» вывести её из (a/b)'=(a * b^-1)'=…
Нет, эта формула ужасна. Применять ее в ситуации деления на x^n — не лучшая идея, слишком много иксов вылазит которые потом сокращать придется.
Ну, не знаю… некоторые и из левой части уравнения в правую с трудом слагаемые переносят.
> Применять ее в ситуации деления на x^n — не лучшая идея, слишком много иксов вылазит которые потом сокращать придется.

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

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

Я в детстве числа представлял в виде длинной ленты с метками. Прообразом была мерная лента для шитья, которая висела в гардеробе. Для сложения и вычитания оперировал оффсетами на этой визуальной ленте и довольно быстро. Еще пытался умножение делать. Дальше дело не пошло :-)
Такие же оффсеты, как и при сложении. Только мерная лента слегка другая, с логарифмической шкалой :)
Только вот какой в этом смысл? Как это первокласнику обьяснить?
Я думаю что возможность быстро «щёлкать» в первую очередь связана с качеством выстроенной модели в голове. По моему мнению количество решённых примеров влияет только на закреплении этой модели.
Если модели в голове по какой то причине нет, то не важно сколько вы решили задач, это просто форма зубрёжки.
Вы построили такую вот зависимость: отличник -> много запоминает -> пишет длинные функции.
И первое условие не всегда верное, а уж второе-то…
успеваемость по таким предметам, как чтение и математика, напрямую связана с рабочей памятью

Эллоуэй Трейси, глава «Рабочая память и коэффициент интеллекта IQ» из книги «Включите свою рабочую память на полную мощь».

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

Рабочая память, Википедия.

Так что первое условие я не придумал. А второе условие — да, это гипотеза, о чём я так прямо и написал. И мне хотелось бы обсудить её. Может быть, следовало обратиться к сообществу психологов? Однако затронутая проблема касается именно программистов, поэтому я предпочёл хабр.

Я сделал определённые выводы, и мне интересно, что о них думают мои собраться по профессии. Прошу высказываться!
Это теория.
Непомерно длинные функции что я видел были написаны или в режиме «на отвали», или фрилансерами(по сути тоже что и первое) или по старой памяти с более низкоуровневых языков. Программисты которые сильно умны, думают не только об уравнениях, но и о качестве кода и его последующей поддержке или они не очень-то и умны как по мне.

Умные программисты знают, что:


  1. Есть менее умные, но при этом не менее полезные.
  2. Мозг не всегда одинаково хорошо думает.
Таких стоит называть «мудрые программисты», чтобы отличать их от просто умных ))
Не надо ничего вводить в абсолют — мы не на дваче.
О! Знаменитый reload. Для него даже отдельная статья в Wiki есть.

По-моему достаточно одной цитаты: Reload is the GCC equivalent of Satan, чтобы понять как к ней относятся разработчики…

Не думаю, чтобы её писали «на отвали», скорее «так уж вышло»… но да — это не то, чем можно гордится.
Я к этому и вёл: что длинные запутанные функции появляются как в случае «писали на отвали», так и в случае «так уж вышло». GCC и его reload — далеко не уникальный случай.
Или в случае «хотели оптимизировать». Дополнительный вызов — это хоть и небольшие, но накладные расходы. Если можно их избежать — стоит избежать. Во всяких парсерах и компиляторах как раз я очень понимаю их наличие: огромная портянка из if-ов. При этом:

1) Можно настроить IDE на схлопывание всех этих if-ов и расставить границы блоков фолдинга, и всё сразу станет коротко и изящно (ну если не открывать код в обычном редакторе, разумеется).
2) Если мы пишем реально что-то очень длинное, типа автомата — у нас неизбежно будет много if-ов, но мы не можем просто так взять, и использовать вызов других методов, если мы пишем в ООП, поскольку тогда мы потеряем доступ к переменным состояния, которые так мы можем сделать локальными, а в противном случае придётся хранить их или как поля объекта (что выглядит безобразно), или завести объект с набором всех этих данных и передавать его как аргумент другим методам, заменив if-ы на вызовы этих методов. Как по мне, затраты по памяти и циклам CPU на создание и передачу такой структуры не стоят того, чтобы сделать основной метод «в пределах разумного по длине».

Тем более, такие методы очень редко правятся, а если и правятся, то людьми, которые очень в теме того, что там внутри происходит :)
Можно настроить IDE на схлопывание всех этих if-ов

Для ясности: там не тело ифа на два экрана, а само его условие.
Условия ифов ваша IDE тоже схлопывает?

Тем более, такие методы очень редко правятся, а если и правятся, то людьми, которые очень в теме того, что там внутри происходит :)

Ну естественно, что раз код с одного взгляда вызывает желание закрыть его и больше никогда не открывать, — то он будет правиться очень редко и только теми людьми, кто смогут в себе эту естественную реакцию подавить.
Условие на два экрана — это уже диагноз :D
Дополнительный вызов — это хоть и небольшие, но накладные расходы. Если можно их избежать — стоит избежать. Во всяких парсерах и компиляторах как раз я очень понимаю их наличие: огромная портянка из if-ов.

А я не понимаю.

Такой код нетестируем и неподдерживаем, а вот код на каких-нибудь там монадных комбинаторах — вполне себе. При этом компилятор вполне может все лишние вызовы функций заинлайнить: не зря на boost.spirit получаются одни из самых быстрых парсеров.

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

Если мы пишем реально что-то очень длинное, типа автомата — у нас неизбежно будет много if-ов, но мы не можем просто так взять, и использовать вызов других методов, если мы пишем в ООП

А просто не надо писать стейтмашины в ООП.
Такой код нетестируем и неподдерживаем

Весьма спорное утверждение. Очень даже поддерживаем. А тестирование — ну да, тут сложнее, надо сразу писать без ошибок, иначе потом дебажить не так просто. Хотя тоже возможно, устанавливая точки останова в нужные if-ы прямо в начало.

А просто не надо писать стейтмашины в ООП.

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

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

А тестирование — ну да, тут сложнее, надо сразу писать без ошибок, иначе потом дебажить не так просто.

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

Хотя тоже возможно, устанавливая точки останова в нужные if-ы прямо в начало.

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

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

Почему не надо, и какие альтернативы, если нам надо парсинг делать?

А у вас ООП фиксированный констрейнт или необходимость распарсить язык? Откажитесь от ООП [в этой задаче].

К тому же, стейтмашина под конкретный язык — будет быстрее регулярок, причём в разы, имхо.

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

При должном упорстве можно минимальный DFA построить даже в компилтайме.
Если у вас грамматика языка зафиксирована один раз и навеки, то, пожалуй, да, потому что поддерживать и не надо.

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

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

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

А у вас ООП фиксированный констрейнт или необходимость распарсить язык? Откажитесь от ООП [в этой задаче].

У меня констрейнт — язык разработки. Вы таки сможете написать парсер на Java, не используя ООП?)

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

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

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

А не подскажете, что называется комбинатором? Я просто только недавно начал изучать эту тему :)
А разве бывает иначе (если мы пишем парсер существующего, а не своего языка)?

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

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

Но регулярка как инструмент более универсальна, т.к. может тестировать что угодно, а не только конкретную грамматику.

Конкретная регулярка точно так же тестирует конкретную грамматику. Конкретную регулярку вы можете скомпилировать в автомат (всякие там JIT в pcre и подобных или тот же уже обикавшийся в этом треде ragel).

У меня констрейнт — язык разработки. Вы таки сможете написать парсер на Java, не используя ООП?)

Я вообще не смогу написать на Java, потому что я её не знаю.

Но вообще печально, конечно, когда нельзя выбрать язык под задачу.

А не подскажете, что называется комбинатором? Я просто только недавно начал изучать эту тему :)

Ну, в программировании (в ФП, в частности) в первом приближении это относительно любая функция высшего порядка. Например, вы можете написать комбинатор many, который будет принимать парсер A и возвращать парсер, распознающий A*. Можете написать комбинатор chain, принимающий два парсера и возвращающий парсер, склеивающий их. Можете написать комбинатор many1, эквивалентный Kleene plus вместо star и работающий как many1 p = chain p (many p).

Вот, например, список таковых парсеров в одной из каноничных библиотек.

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

Потом, Вы сказали, что pcre может компилировать регулярки. Но pcre — это стандарт синтаксиса. А ещё есть реализации pcre в разных языках программирования. Вы правда уверены, что они всегда всё компилируют и кэшируют, а не считают всё в рантайме (и даже что можно косвенно на это поведение влиять)? Я вот нет :) Потому и предположил, что без регулярок будет работать быстрее (и контроля больше).
А что насчёт производительности этого процесса (получения парсера из парсера)? Я правильно понимаю, что для нас это «чёрный ящик», и мы не профилируем никак этот код?

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

Потом, Вы сказали, что pcre может компилировать регулярки. Но pcre — это стандарт синтаксиса.

Я про libpcre.
А что там с джавой?) Она точно использует эту либу под капотом?)
Это на джаву смотреть надо, я про неё саму довольно мало знаю, а уж про детали реализации — тем более.
Почему не надо, и какие альтернативы, если нам надо парсинг делать?
Самый обычный Ragel, если вам именно стейт-машина и Bison не подходит.

То, что у вас одна большая процедура в коде не означает, что исходник точно так же должен выглядеть…
У Ragel проблема в том, что оно обязательно генерирует DFA (по крайней мере, я за разумное время не нашёл, как этого избежать), что на некоторых регулярках приводит к экспоненциальному взрыву числа состояний.

Самописный NFA на хаскеле работал не сильно медленнее (там, где Ragel'у таки удавалось что-то выплюнуть, не сожрав пару сотен гигов памяти и не уйдя в своп).
Декомпозиция никак не влияет на тестируемость, это распространенный миф. Тестами покрывается не код, а граф потока управления (чего многие почему-то не понимают). При разбиении одной большой ф-и на много мелких — граф потока не меняется. При замене ифа лямбдой/наследованием — граф потока не меняется.

Несложно переписать любой код на лямбды так, чтобы никаких ифов там вообще не было. Код станет более тестируемым, что ли? Нет. А именно это происходит в случае с комбинаторами.
Граф потока от декомпозиции еще как меняется: в нем появляются новые точки входа и выхода.
Нет, не появляются. Откуда бы им появиться? Просто современный подход к тестированию — не про инженерию, а про рисование красивых циферок и выкрикивание баззвордов. Это ведь смешно, когда фактически один и тот же набор тестов после автоматического рефакторинга (замена ветвлений лямбдами) вам поднимает «покрытие кода» (что это такое кстати, хоть кто-то хоть когда-то смог дать корректное определение для языка с поддержкой указателей/ооп/лямбд?) в сотню раз, при этом количество потенциальных ошибок, которые данный набор тестов способен найти, никак не меняется и логика приложения — тоже не меняется.
Никто не говорит про автоматический рефакторинг с обмазыванием лямбдами вместо ветвлений, это не имеет смысла. Смысл имеет замена ветвлений функциями вроде choice, many, many1, optional и так далее, с чётко определённой семантикой и единожды проверенной реализацией.

Какая-то непонятная мне борьба с соломенными чучелами из автоматических рефакторингов и погони за метриками вроде покрытия кода (которое, вы абсолютно правы, смысла не имеет даже в языке не то что с ООП/лямбдами, а хотя бы с условным оператором, лучше хотя бы думать о покрытии бранчей, если так метрик хочется).
> Смысл имеет замена ветвлений функциями вроде choice, many, many1, optional и так далее, с чётко определённой семантикой и единожды проверенной реализацией.

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

> с чётко определённой семантикой и единожды проверенной реализацией.

У if семантика тоже четко определена и неединожды проверена.

> лучше хотя бы думать о покрытии бранчей, если так метрик хочется

Я покрытие бранчей и имел ввиду. Но проблема в том, что любой виртуальный вызов, передача лямбды или указателя на ф-ю, дает потенциально бесконечное количество бранчей, по-этому покрытие всегда 0%.
Но это и есть обмазывание лямбдой вместо ветвления. Ветвление в данном случае никуда не уходит.

А функции — всего лишь сахар над goto, функции не нужны, все на goto!

В графе потока управления как была вилка, так и осталась вилка. И эту вилку надо тестировать.

Зачем вам каждый раз тестировать, что делает условный many1?

У if семантика тоже четко определена и неединожды проверена.

Только она чуть более базова и посему неизбежно чуть более обща.

Но проблема в том, что любой виртуальный вызов, передача лямбды или указателя на ф-ю, дает потенциально бесконечное количество бранчей, по-этому покрытие всегда 0%.

Вы имели в виду бесконечное количество последовательностей бранчей? Да, с этим трудно спорить.
Так всегда O(mn) тестов надо. А если провели декомпозицию — то еще больше (тоже mn, но скрытая константа выше)
Потому что вы можете протестировать каждый комбинатор в отдельности, опять же. Да и проще рассуждать о том, что от добавления нового комбинатора у вас не сломаются имеющиеся (при постепенной реализации грамматики, например). Да и зависимости-переходы между комбинаторами сразу видно, и легко отвечать на вопрос «где используется этот кусок грамматики комбинатор».

Просто на всякий случай, мы правда обсуждаем, что лучше — функция на 1000 строк с полсотней ифов (пусть и в известном смысле минимальная такая функция), или же набор из полсотни мелких и удобных комбинаторов (тоже, для честности сравнения, в известном смысле минимальный)?
Просто на всякий случай, мы правда обсуждаем, что лучше — функция на 1000 строк с полсотней ифов (пусть и в известном смысле минимальная такая функция), или же набор из полсотни мелких и удобных комбинаторов (тоже, для честности сравнения, в известном смысле минимальный)?
Да. Я, впрочем, не буду заявлять, что «граф потока не меняется» от декомпозиции, но был у нас случай, когда мы хотели всё сделать «серьёзно», «по-настоящему безопасно».

И оказалось, что надёжнее всего не доказывать какие-то свойства «полсотни мелких и удобных комбинаторов» — а просто взять сгенерированную ragel'ем функцию, рассмотреть свойства языка, который она принимает — и всё. Не требуется знать и проверять все сотни DFA, из которых «собрана» функция, не требуется доказывать что ragel их правильно комбинирует… просто берём граф и изучаем его свойства.

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

P.S. Только не надо говорить «вы же всё равно собрали свой автомат из комбинаторов». Да — так нам показалось удобнее. Но тестировали мы именно функцию на 1000 строк (на самом деле на 100'000 строк, но не принципиально) — если бы она была написана руками с точки зрения тестирования ничего бы не поменялось.
И оказалось, что надёжнее всего не доказывать какие-то свойства «полсотни мелких и удобных комбинаторов» — а просто взять сгенерированную ragel'ем функцию, рассмотреть свойства языка, который она принимает — и всё. Не требуется знать и проверять все сотни DFA, из которых «собрана» функция, не требуется доказывать что ragel их правильно комбинирует… просто берём граф и изучаем его свойства.

То есть, вы взяли сгенерированный ragel'ом код, в известном смысле отреверсили его и что-то про него доказали?

А зачем? Почему бы не изучить то, что вы скормили ragel'у в предположении о том, что ragel корректен?

Не требуется знать и проверять все сотни DFA, из которых «собрана» функция

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

И фишка была в том, что мы хотели уменьшить как можно сильнее обьём кода, которому нам приходится доверять. Но… так тоже бывает.

А, вот зачем. Ну libc, компилятор и, чего мелочиться, микрокод вы, надеюсь, тоже верифицировали?

Ну и лично мне (особенно после попыток вручную ковырять выплеванное ragel'ом, причём для тестовых примеров на отдельные комбинаторы, которые я компилировал в ragel, был у меня такой опыт) кажется, что проще было бы верифицировать сам ragel.

Но тестировали мы именно функцию на 1000 строк (на самом деле на 100'000 строк, но не принципиально) — если бы она была написана руками с точки зрения тестирования ничего бы не поменялось.

Было бы интересно сравнить время разработки этой функции руками и через ragel.
То есть, вы взяли сгенерированный ragel'ом код, в известном смысле отреверсили его и что-то про него доказали?
Угу.

А зачем? Почему бы не изучить то, что вы скормили ragel'у в предположении о том, что ragel корректен?
Потому что, во-первых, были сомнения в корректности рагеля. Неизвестно — корректен ли он, но точно нестабилен: одинаковые входы дают на машинах разных разработчиков разные (хотя и эквивалентные) выходы. Чтобы это побороть мы перешли от прямой генериации кода ragelем к ragel -x с последующей генерацией кода уже нашим скриптом). Что, кстати, облегчило и исследование тоже.

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

А, вот зачем. Ну libc, компилятор и, чего мелочиться, микрокод вы, надеюсь, тоже верифицировали?
libc и компилятором занимаются другие люди. А ragel'ем никто не занимается. Микрокод вне Intel никто исследовать не может… хотя и очень хочется — там точно есть баги, неизвестно только, насколько страшные. У security team есть идеи по этому поводу — но они под NDA, потому про них пока рано говорить. Но мне нравится ход ваших мыслей.

Было бы интересно сравнить время разработки этой функции руками и через ragel.
Это тяжело будет сделать. Но сама эта функция заменила более старую подсистему, которая как раз была написана в «полноценном ООП-стиле». Ну там интерфейсы всякие и композиция в рантайме.

В программе у нас два режима — более «точный» и менее «точный». Соотвественно в оригинальной программе был флаг, а в случае с DFA — было две независимых DFA. Только менее точная была в 100 раз меньше, чем старая подсистема (и работает в 20 раз быстрее), а более точная — примерно то же самое по обьёму (но в 10 раз быстрее).
Неизвестно — корректен ли он, но точно нестабилен: одинаковые входы дают на машинах разных разработчиков разные (хотя и эквивалентные) выходы.

А это было для вас недостатком?

Известно ведь, что, скажем, минимальный DFA уникален, но с точностью до изоморфизма (и если вы выходом считаете конкретные метки конкретных состояний, то они будут различаться). Неминимальных вообще много, и ЕМНИП ragel не всегда старается получить именно минимальный.

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

Это (и связь с objdump) я вот не понял. Видимо, это уж слишком завязано на вашу конкретную задачу.

libc и компилятором занимаются другие люди.

И они правда занимаются верификацией какого-нибудь современного gcc или clang? Или вы используете что-нибудь вроде gcc 3.3 или 4.2 из условной МСВС?

А ragel'ем никто не занимается.

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

Но это, конечно, зависит от того, как часто вам нужно такие финты проворачивать. Вы вон сами пишете, что оно вам встречалось раз в жизни.

Но сама эта функция заменила более старую подсистему, которая как раз была написана в «полноценном ООП-стиле». Ну там интерфейсы всякие и композиция в рантайме.

Я плохо себе представляю, кто и зачем в здравом уме будет писать парсеры в ООП-стиле, с интерфейсами и композицией в рантайме.
Неизвестно — корректен ли он, но точно нестабилен: одинаковые входы дают на машинах разных разработчиков разные (хотя и эквивалентные) выходы.
А это было для вас недостатком?
Это риторический вопрос? Вам слова «reproducible builds» о чём-нибудь говорят?

Это (и связь с objdump) я вот не понял. Видимо, это уж слишком завязано на вашу конкретную задачу.
Угу.

И они правда занимаются верификацией какого-нибудь современного gcc или clang?
До формальной верификации — им ещё как пешком до луны. Пока речь идёт о самых базовых вещах. В частности нужно, чтобы builds были reproducible, а то непонятно — что с чем сравнивать. Но да, в идеале дойти до формальной верификации — было бы неплохо.

Я плохо себе представляю, кто и зачем в здравом уме будет писать парсеры в ООП-стиле, с интерфейсами и композицией в рантайме.
Можете попробовать догадаться. Hint: это связано с предыдущим абзацем, который вы не поняли. Люди писавшие первую версию, не осознавали, что они, на самом-то деле, пишут парсер некоего языка.
Это риторический вопрос? Вам слова «reproducible builds» о чём-нибудь говорят?

Это с одной и той же версией ragel? Тогда да, тогда это не очень хорошо (а на самом деле очень нехорошо).
Это с одной и той же версией ragel? Тогда да, тогда это не очень хорошо (а на самом деле очень нехорошо).
Не только «та же самая версия». Тот же самый бинарник.

Причём на простых DFA вроде такого не случалось. А когда обнаружили — было поздно уже всё переделивать.

Он там когда машину строит — один из вариантов выносит в switch в default, а остальное — уже обрабатывает. При этом выносит так, чтобы минимизировать размер кода, но если вариантов выноса два или больше — может на разных машинах разные интервалы выносить.
При этом выносит так, чтобы минимизировать размер кода, но если вариантов выноса два или больше — может на разных машинах разные интервалы выносить.

Я всё равно плохо представляю, как это может быть недетерминировано в данном случае. Ну да ладно.
Представьте себе, что у вас есть вариант перейти для 0..127 в одно состояние, а для 128..255 в другое.

Вы можете написать switch и 128 меток от 0 до 127 (а 128...255 пойдут в default) или 128 меток от 128 до 255 (а 0..127 пойдут в default).

Вот на одних машинах ragel выбирает первую альтернативу, а других — вторую.

P.S. На самом деле ragel умнее и если у вас есть только два таких диапазона — будет использовать if. Проблемы начинаются когда у вас есть несколько диапазонов одинакового размера и несколько отдельных вариантов.
Вы имеете в виду 127 условий? Просто если это тупо одна величина — я не очень понимаю, зачем 128 меток городить, когда простого сравнения достаточно…
Не требуется знать и проверять все сотни DFA, из которых «собрана» функция.
Ну да, требуется всего лишь проверить их композицию, что, конечно, легче.
Таки да, легче. Тут проблема в том, что ragel не совсем на DFA оперирует. В частности если у вас есть машина принимающая a и печатающая Yes, this is a! и другая машина, принимающая ab и перечающая Yes, this is ab!, то их композиция напечатает обе строчки получив на вход ab.

Это, зачастую, упрощает его использование на практике, но сильно усложняет теоретическую оценку правильности результата. Если же мы рассматриваем только конечный автомат «в сборе» — то это проблемой для нас не является…
Это была одна из причин, почему я в итоге отказался от ragel и заменил его своей реализацией NFA simulation — там какая-то наркомания с приоритетами, жадностью и смежными вещами, некоторые крайние случаи которой мне победить не удалось.

Но, в любом случае, если у вас есть относительно формальное описание того, что значит «композиция» в терминологии ragel'а, то про это уже можно доказывать всякие интересные вещи.
Но, в любом случае, если у вас есть относительно формальное описание того, что значит «композиция» в терминологии ragel'а, то про это уже можно доказывать всякие интересные вещи.
Можно. Но проще оказало не разрабатывать специализированную теорию, а просто посмотреть на результирующий DFA.
У меня такие функции (может, чуть короче) тоже имеются… Конечно, гордиться может и нечем. Но когда код лично твой, и ты понимаешь структуру — ты в нём не запутаешься. Вот если открыть его через год-два-три — уже может быть не очень приятно...)
успеваемость по таким предметам, как чтение и математика, напрямую связана с рабочей памятью

Есть исследования утверждающие что "общий" интеллект нельзя свести к одному фактору:


http://www.cell.com/neuron/abstract/S0896-6273(12)00584-3


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

Причем тут "рабочая память", когда ПО пишут команды разработчиков. Код должен быть понятным и храниться в памяти компьютера, а не в голове конкретного разработчика. Тем-более код по статистике чаще читается, а не пишется. И читается он не только автором, но и его коллегами и т.д.
Длина метода в 100+ строк — это уже не есть хорошо. По этому поводу Макконелл еще давно писал. А его книга "Совершенный код" — это классика, к которой все прислушиваются. У него по поводу размера метода отдельный раздел есть, где он пишет, что метод в идеале должен полностью помещаться на экране монитора (50-80 строк).
Плюс к этому, рекомендуется заменять комментарии, методами с подходящим названием.
А держать методы в уме (что вылетит из бошки очень быстро) — это не правильно, как по мне.

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

Смотрите названия методов, которые эту проверку вызывают :)

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

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

Разумеется. Иначе не быть бы когнитивной психологии отдельной дисциплиной. Вот: «Когнитивная наука. Основы психологии познания» (в двух томах). Суммарно 880 страниц. Можно найти в электронном виде — почитайте содержание ради интереса.
В программировании нет сложных задач. Есть очень-очень-очень много средне-лёгких. Просто их очень много.

Просто нужно придумать как из сложной задачи сделать кучу средне-лёгких. Это возможно самый сложный этап.

В масштабах человечества — наверное, нет. А в масштабах интеллекта конкретного программиста — задачи вполне могут быть на верхнем пределе способностей. Или выше, в патологических случаях ;)
Ну прорешайте десяток-другой задач из project euler, что ли.
Вцелом — не очень согласен.
Если под отличником(-цей) понимать не зубрилу и выскочку (катати как и подлец только мужского рода слова), а способного мальчика или девочку, то точно не согласен что так будет брать производную. Будет расписывать по шагам а не заучивать формулу. У нас в университете даже это просто запрещалось делать. Поэтому решение примера чуть сложднее шекольного например по теме интегралы были на 4-х страницах с двух сторон в каждой клеточке.

Что касается магического числа семь. По этому поводу мне очень хорошо запомнилась байка одного из преподавателей прмышленного дизафна в политехе, где училась моя сестра. Вобщем-то тема была как раз о памяти. По поводу ворон например оказалось что сичтают до трех. Проверяли таким способом. Клали сыр в закрытое помещение куда входили по очереди и потом выходили 1, 2, 3 и 4 человека. Так вот вороны дожидались пока не выйдет 1, 2, 3 человека а на 4-м начали ошибаться.

По поводу человека проводили опыты с пастухами. Забирали у них из стада численностью 1,2,3 и т.п. голов одну корову и просили сказать все ли коровы на месте не пересчитывая их. Пастухи действтельно начинали ошибаться при стаде из 8 коров.

Потом сделали тот же оптыс с оленеводами. Дошли ждос стада в 1000 оленей и оленевод всегда точно отвечал типа Сохатого не хватает, однако.

Тут важен сам подход

А вот тот код написал троеччник или отличник это еще нужно доказать. С кодом функции в пару тысяч строк например я еще могу разобраться. Но если троечник начинает делать все «по науке» и разбивать 50 строк на модули, но не в стиле «раздляй и властвуй», а в стиле: разложи листики в конвертики, потом конвертики сложи в коробочки, коробчки положи в ящички, потом подойди к ящичкам и найди где лежит заначка. То это гораздо более утомительно. Прошлая Ваша публикация на данную тему кажется мне более инересной.
Когда пример лёгкий, как тот, что я привёл в пример в начале поста — такой вполне можно решить в уме и записать сразу готовый ответ. Лично я постоянно так и делал, несмотря на требования расписывать решение по шагам. Ну или хотя бы пропускал половину шагов, потому что влом записывать.

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

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

Про код могу так ответить. «Отличник» и «троечник» здесь — условные категории. Надеюсь, их не будут воспринимать слишком буквально. Надо же было их как-то кратко назвать. Не писать же каждый раз «лица с хорошо развитым подвижным интеллектом» и «лица с не так хорошо развитым подвижным интеллектом».

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

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

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

Да я понимаю о чем Вы хотели сказать. В первой Вашей статье была действительно интересная идея о том что у хорошего программиста-хорошиста код всега очень лаконичный и понятный. В большинстве же своем программисты как и нормальные люди троешники (написал бы троечники но похоже на кучеров троек получается что-то). Мне например сложнее всего вникать в суть не с длинной плохо написанной функици, а предположем 3 функций которые были плохо разбиты на 3 функции. Если Вы дадите троечнику задание разбей свой код на функции он это сделает на ту же самую тройку и будет уже тройка в квадрате.
Некоторые утверждения статьи странные. Константы не нужно держать в голове, что они значат видно прямо из их названия в момент чтения. Насчёт хэшей — точно не уверен, как там в питоне, но в js есть только один вид хэша — получить объект/значение по ключу (и это логично). Причём что это за объект/значение следует прямо из названия хэша. Нужно помнить только сам объект, но и тут его название говорит само за себя: если оно во множественном числе, это массив, если это объект вида user или userObj, то это struct или экземпляр класса, если userId или userCount, то число, если isUser, то boolean и т. д.

А функции да, по возможности нужно разбивать на более мелкие — проанализировать 2 независимые функции по 10 строк намного проще, чем одну из 20 строк. Ну и конечно именование функций, параметров, переменных и т. д. очень важно (а особенно важен API).
Программирование это навык на границе науки и искусства. Задача программиста: декомпозиция задачи на блоки, каждый из которых должно как можно эффективнее использовать повторно. Наука здесь в декомпозиции и решении задачи. Искусство в эмпирическом предсказании возможности повторного использования каждого отдельного блока решения. Этот тезис был известен даже в СССР. С тех пор не изменился.

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

Беда в том, что из-за низкого порога входа такие вот программисты начинают проектировать свои собственные системы. Которые чуть более, чем полностью состоят из таких вот богоподобных функций с кучей предусловий и неясной механикой работы. В таких системах сложные задачи вполне решаются за 150 строк, если вы достаточно «вкурили» странную логику автора. Только вот это будет навык использования этой конкретной системы, а не навык программирования или решения задач.

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

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

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

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

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

Тут возникает другой аспект: какому-нибудь «сеньору», как правило, очевидно, где решение хорошее, а где — плохое, без всяких метрик когнитивной психологии. Эти самые метрики нужны для людей, которые в самой профессии не смыслят. То есть, для внешних управленцев. И мы внезапно оказываемся ну очень далеко от исходной темы.
ёлки, ну и вырвиглаз.
а дело не только в длинне или непонятности синтаксиса но и в общих правилах структурирования кода
Ой, тоже мне нашли беду. Это ж парсер параметров. Сравните с GNU LD'шным.

Простая функция, пусть и довольно длинная.
Наименование переменных :(

Первая же строчка:
int r, c;

Что такое r и что такое c? Это первая строчка функции! Хотя бы коммент оставили.

Хотя фиг знает, может это общепринятное соглашение, и эти r и c используются 100 раз в коде, но что-то я сомневаюсь, что они писали 100 похожих парсеров.

И почему функция парсера конфига ничего не возвращает? Причём с первой же строчки начинает менять глобальные переменные. Глобальные надо менять, когда реально состояние приложения изменилось. А тут всего лишь парсер конфига.
Что такое r и что такое c? Это первая строчка функции! Хотя бы коммент оставили.
Зачем? Посмотрите где они инициализируются — и всё станет ясно.

C99 ещё не везде, так что да, приходится описывать переменные в начале функции, а не там, где они нужны…

Хотя фиг знает, может это общепринятное соглашение, и эти r и c используются 100 раз в коде, но что-то я сомневаюсь, что они писали 100 похожих парсеров.
Ноборот — они там 5 строчках используются. И в них легко понять — что это за переменные и что они делают.

Вы пытаетесь читать программу на C89 опираясь на подходы какого-то другого языка (C++? Python?) — отсюда сложности.

Глобальные надо менять, когда реально состояние приложения изменилось.
Опять-таки — это подход современных языков и современных приложений. Которые, типа, могут прочитать конфиг и поменять его «на лету» (ага, три раза). Программки на C обычно читают конфиг один раз и если он неправильный — выдают ошибку. Зачем тут лишние сущности устраивать?
Понял, да, я применял подходы других языков. Просто я обычно даю переменным имена, которые явно показывают, для чего они предназначены. Сокращать до одной буквы очень редко имеет смысл.
Просто я обычно даю переменным имена, которые явно показывают, для чего они предназначены. Сокращать до одной буквы очень редко имеет смысл.
Старая привычка от которой просто сложно отказаться. Как с курением.

Старые мониторы (80x24), нет IntelliSense… а переменные нужно обьявлять в начале функции в C89 (до первого оператора). Когда-то это имело смысл. А если ты пишешь 10+ лет в таком стиле, то уже как-то и не видишь ничего страшного в одной букве. c(haracter), s(tring), p(ointer) — наиболее частые сокращения. «r»… думаю r(ead result) имелся в виду.

То есть да — не могу сказать что это прям код — верх изящества, но он вполне в духе «old school» и не сказать чтобы уж прям ужас-ужас…

P.S. Вообще, конечно же, лучше описывать переменные где используешь… C99 и C++ не зря придумали (и давно), но грехи (Windows и MSVC) не пускают…
c — character, s — string, f — function, p — pointer — это всё нормально. Но там попался какой-то «r».

Но ещё в своём языке я привык объявлять переменные по мере использования. Просто const c — такого не бывает, а вот const c = s[i] — может быть, т. е. несмотря на короткое имя, назначение очень понятно.

Но таких коротких переменных можно пересчитать по пальцем, даже a — array — не всегда хороший вариант, потому что если это не совсем временная переменная, лучше назвать users, к примеру. А там все переменные так названы =)
Один из признаков хорошего программиста, на мой взгляд — умение переучиваться и обновлять свои привычки в соответствии с изменяющимися условиями.

Это было бы «ну так себе нормальненько», если бы этому коду было лет 30, а не 9.
C99 ещё не везде, так что да, приходится описывать переменные в начале функции, а не там, где они нужны…

Конкретно в этом коде переменные в середине функции объявляются. (int was_created = -1;) — мне это сразу резануло глаза. Не знаю что в этой "фиче" хорошего, тоже писал так 10 лет назад по глупости, потом перестал.

Не знаю что в этой «фиче» хорошего, тоже писал так 10 лет назад по глупости, потом перестал.
Хорошего то, что легко можно увидеть где и как эта переменная используется.

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

Только мне кажется, что проект, который «consisting of efficient PHP-to-C++ translator called «KPHP» or «KittenPHP», and several auxiliary high-performance «engines» (specialized non-relational databases), needed for its deployment», может позволит себе опираться хоть на С++11, хоть на хаскель.

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

Потому что о программах без глобального состояния проще, как это говорится, reason about. Можно посмотреть на входы и выходы каждой функции и сделать выводы, с чем она работает и от чего она зависит, а также что она меняет и на что может повлиять.

Чтение много раз — дело десятое.
Потому что о программах без глобального состояния проще

Не всегда. А в случае высоконагруженного специализированного процесса — почти всегда наоборот. А если точнее, то "глобальное состояние" там — это состояние всего сервера (железки) с операционной системой. А любой процесс — уже локален, считайте что это экземпляр объекта "сервер" со своими полями. Вас же не смущает, когда методы класса меняют состояние класса, а не только свои локальные переменные? А оверхед "модного ооп-кода" убрали — он тут ни к чему, экземпляр этого объекта строго один на процесс, а может быть и на серверную железку, и поддержка нескольких экземпляров одновременно только создаёт лишнюю нагрузку (например обратиться к this->a всегда сложнее чем к глобальной переменной a).

А в случае высоконагруженного специализированного процесса — почти всегда наоборот. А если точнее, то «глобальное состояние» там — это состояние всего сервера (железки) с операционной системой.

Почему специализированный у нас процесс, а состояние — вся железка?

Вас же не смущает, когда методы класса меняют состояние класса, а не только свои локальные переменные?

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

И классы с большим количеством состояния меня тоже смущают.

например обратиться к this->a всегда сложнее чем к глобальной переменной a

Если объект на стеке, то нет. Если объект на хипе и короткоживущий, то по сравнению с лишним дёрганием хип менеджера это ничто. Если объект на хипе и долгоживущий и в горячем коде, то бранч индирекшон предиктор быстро обучится.
Почему специализированный у нас процесс, а состояние — вся железка?

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


то бранч индирекшон предиктор быстро обучится.

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

Потому что там ещё было слово «высоконагруженный». В таких случаях на каждого функционального демона выделяется своя железка, а то и несколько железок (как в вк).

И выделяется одна железка под высоконагруженный парсер конфигов?

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

Вы правда уверены, что парсинг конфигов — горячая часть этого сервиса?

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

И да, индирекшон всё равно есть.
В смысле, просто запись такая? Его ж линкер (или ОС при загрузке, если это шаредлиба и PIC, но это не шаредлиба) подправляет.
Нет. Его линкер/загрузчик не подправляет, учите матчасть.

В 32-битном режиме адрес задаётся прямо в команде. А в 64 битах так сделать нельзя: требовалось бы 64-битное смещение, что расточительно.

Потому кроме режима абсолютной адресации, который позволяет добраться только до первых 4GB (на самом деле первых 2GB и последних 2GB, но не суть), в x86-64 есть ещё и «адрес относительно текущей инструкции». И в 64-битном режиме именно он и используется обычно. Вот именно его мы видим по вашей ссылке.

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

А при обращении к «обычному» регистру ничего подобного сделать нельзя. Там — нужно «вынуть» адрес из регистра, возможны разного рода задержки и прочее.
Потому кроме режима абсолютной адресации, который позволяет добраться только до первых 4GB (на самом деле первых 2GB и последних 2GB, но не суть), есть ещё и «адрес относительно текущей инструкции». И в 64-битном режиме именно он и используется обычно. Вот именно его мы видим по вашей ссылке.

А адрес глобальной переменной относительно текущей инструкции на каком этапе становится известен?

А при обращении к «обычному» регистру ничего подобного сделать нельзя. Там — нужно «вынуть» адрес из регистра, воможны разного рода задержки и прочее.

Какого рода задержки? В горячем коде оно и так всё будет хорошо.
А адрес глобальной переменной относительно текущей инструкции на каком этапе становится известен?
Зависит от настроек компиляции. Обычно на этапе статической линковки, но бывают и исключения. Смотрим сюда. Первое окошечко — главная программа, там индирекции нет. Второе окошечко — разделяемая библиотека, скомпилированная нормальным программистом, там тоже индирекции нет. Третье окошечко — варинт «на отвали», там индирекция есть.

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

P.S. Впрочем обычно потеря 10-15% скорости не так критична, как потеря безопасности. Потому глобальные переменные сейчас часто не используют даже для очень «горячего кода». Но таки задержки эти есть — даже на самых современных процессорах.
Обычно на этапе статической линковки, но бывают и исключения.

Нет. Его линкер/загрузчик не подправляет, учите матчасть.

Ну ладно :)

Это уже лучше на личной машине попробовать, из godbolt'а мне не удалось выковырять нужный выход, но соберите на x86_64 бинарь из двух файлов (с пустой doFoo() рядом, например) и сравните его дизасм с дизасмом объектного файла из одного только main. Во втором случае там будет что-то вроде 0(%rip), который именно что заполняется линкером.

А загрузчик в ОС — как раз эти самые ваши исключения, по крайней мере, для не-PIC-кода (я в исходном комментарии описался на эту тему, да).

Ну и опять же,
Первое окошечко — главная программа, там индирекции нет.

С точностью до определений, считать foo(%rip) за индирекцию или нет.

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

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

В зависимости от режима адресации могут получиться задержки на такт из-за необходимости пересылки адреса из блока вычисляющего адрес в ALU. Для «горячего» кода — это прилично.

Если класс на стеке, то там скорее всего оно всё относительно (%rsp), и опыт показывает, что можно забить.

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

Самое главное-то в контексте дискуссии я изначально забыл, сбился с этим человеческим reason about code. Компилятору-то тоже проще оказывается о коде рассуждать: посчитайте количество сторов в m_x и в a здесь. То есть, не, понятно, если static добавить, то всё становится очень сильно лучше, но в исходном-то коде никакими статиками и не пахнет!

Но как-то мы уже далеко не в ту степь зашли, ИМХО, и всерьёз обсуждать качество кода для парсинга опций в контексте высоконагруженных серверов — это та ещё импликация, но выводить её некорректность лень и непродуктивно.
Это уже лучше на личной машине попробовать, из godbolt'а мне не удалось выковырять нужный выход, но соберите на x86_64 бинарь из двух файлов (с пустой doFoo() рядом, например) и сравните его дизасм с дизасмом объектного файла из одного только main. Во втором случае там будет что-то вроде 0(%rip), который именно что заполняется линкером.
О боги. Вам про разницу между статическим и динамическим линкером никто не рассказывал? И про то, что relocationы бывают динамическими и статическими? О чём мы тогда, вообще, тут говорим?

Конечно в обьектном файле там будет 0(%rip)! А вот уже в исполняемом файле или в динамической библиотеке — там будет конкретное число.

Вы, я извиняюсь, обьектный файл собрались запускать или как?

А загрузчик в ОС — как раз эти самые ваши исключения, по крайней мере, для не-PIC-кода (я в исходном комментарии описался на эту тему, да).
Ну нельзя так. Просто нельзя. Если вы понятия не имеете о том, как работают обьектные файлы, динамические библиотеки и загрузчик OS — то не очень понятно, о чём дальше говорить. Почитайте хотя бы Drepperа, что ли…

С точностью до определений, считать foo(%rip) за индирекцию или нет.
Давайте не считать ангелов на кончике иглы, а? Мы вроде об эффективности говорим. То, что существует в промежуточном представлении, но не в итоговом бинарнике на эффективность ну никак не может влиять. А вопросы терминологии — не так важны и интересны.

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

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

Но как-то мы уже далеко не в ту степь зашли, ИМХО, и всерьёз обсуждать качество кода для парсинга опций в контексте высоконагруженных серверов — это та ещё импликация, но выводить её некорректность лень и непродуктивно.
Это вы не в ту степь зашли, судя по вашим примерам.

Вы уже не просто «за деревьями не видите леса», а обсуждаете какие-то трещинки на поверхности коры, не обращая внимание на то, является ли этот кусок коры ещё частью дерева или нет.

Давайте я попробую вам лес показать? Это же несложно!

  1. Время разбора конфи гурационного файла — мало кого интересует. За исключением очень редких и патологических случаев — это очень быстро даже если конфигурационные файлы большие и сложные.
  2. Время обращения к данным (флагам и разным настройкам), напротив, может быть очень критически важным и может случаться даже в самых внутренних циклах (например какой-нибудь флаг может влиять на количество вызовов VRECPS в вашем алгоритме).
  3. Если ваша программа не требует хитрых «атомарных» изменений конфига «на лету», то результат разбора конфига разумно поместить в набор глобальных переменных
  4. А вот уже временные переменные, предназначенные только для разбора конфига — лучше бы в глобальные переменные не класть. Тут я согласен. Ибо на скорость не влияют, а место занимают.

В это смысле у GNU LD парсер почище будет. Я больше про него думал, чем про пример от VK. Пример от VK, конечно, доставляет. Код в стиле C89, но при этом с кучей C99 фич — это нечто. Кто и зачем такое пишет — мне непонятно.

Зачем rpc_default_ct глобал — я могу понять. И даже то, что парсер конфигов всё прямо туда пишет — не страшно. Но вот зачем делать глобальной переменную config_buff — загадка, этого я ничем обьяснить не могу…
О боги. Вам про разницу между статическим и динамическим линкером никто не рассказывал? И про то, что relocationы бывают динамическими и статическими? О чём мы тогда, вообще, тут говорим?

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

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

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

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

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

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

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

Вы уже не просто «за деревьями не видите леса», а обсуждаете какие-то трещинки на поверхности коры, не обращая внимание на то, является ли этот кусок коры ещё частью дерева или нет.

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

Давайте я попробую вам лес показать? Это же несложно!

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

Зачем rpc_default_ct глобал — я могу понять.

А я не могу. Я вообще много чего не могу понять, но это уже придирками выглядит на общем фоне.
Почему 63 байта на длину хоста магическим числом? Где ещё 63, 62 и 64 вылезает из проверок?
Почему после некоторых syntax есть return?
Что за танцы с s и c на строках 1520-1521 и потом на 1534-1535? За что так ненавидеть читающего код?
А тестами это вообще покрыто? А как автор покрывать будет? Куда послал, я не расслышал?

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

И там хорошо видно — у вас либо GOT, две инструкции и %rbx, либо одна инструкция, прямой доступ и %rip. То есть да — если у вас переменнай экспортируется из библиотеки, то доступ к ней будет через индирекцию — но и обычный регистр, не %rip

Как-то я упустил пропажу таких выражений из итогового бинарника. Если с малым влиянием ввиду лёгкости работы для декодера (но это нужно бенчмаркать) я ещё готов согласиться, то это уже как-то перебор.
Из бинарника пропадают релокейшены. Правда-правда. Ну проверьте:
$ cat test.c
int i;
int main() {
  return i;
}
$ gcc -O3 -c test.c -o test.o
$ objdump -dr test.o

test.o:     file format elf64-x86-64


Disassembly of section .text.startup:

0000000000000000 <main>:
   0:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # 6 <main+0x6>
			2: R_X86_64_PC32	i-0x4
   6:	c3                   	retq   
$ gcc -O3 test.o -o test
$ objdump -dR test 

test:     file format elf64-x86-64


Disassembly of section .init:

...
Disassembly of section .text:

0000000000000530 <main>:
 530:   8b 05 f6 0a 20 00       mov    0x200af6(%rip),%eax        # 20102c <i>
 536:   c3                      retq   
 537:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
 53e:   00 00 
...


Как видите всё было сделано на этапе сборки бинарника, ничего для динамического линкера не осталось…

Эти флаги можно отдельно внутрь горячего кода и передать (и я бы сказал, что и нужно).
Ну это вопрос очень и очень философский. Глобальный флаг — быстрее. Передача в горячий код — медленнее, но более гибко.

3 — нет. Это не дело кода, парсящего конфиги.
А почему, собственно?

Я, как бы человек простой. Если в меня начинают бросаться всякими вумными словами типа «неSOLIDно», «нарушение инкапсуляции» и прочее, то я обычно останавливаю этот поток сознания и прошу снизойти до «простых смертных». И описать пример цепочки начиная с бизнес-требований.

Ну то есть «если мы сделаем по-другому и владелец нашего бизнеса потребует X, для чего нам потребуется Y и мы можем это сделать без переписывания половины программы только если у нас будет выполняться условие Z»… ну и кончаться это должно заключением «вот поэтому -это не дело кода, парсящего конфиги». Иначе — это архитектурная астронавтика какая-то.

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

Почему 63 байта на длину хоста магическим числом?
RFC1025: labels must be 63 characters or less.

Где ещё 63, 62 и 64 вылезает из проверок?
Не понял вопроса.

Что за танцы с s и c на строках 1520-1521 и потом на 1534-1535? За что так ненавидеть читающего код?
Кто вам сказал, что читающего код здесь кто-то ненавидит? gethostbyname требует там '\0', а мы там имеем что-то другое… что такого странного в том, чтобы записать туда требуемый '\0', а потом вернуть всё «как было»?

А тестами это вообще покрыто? А как автор покрывать будет? Куда послал, я не расслышал?
А для вас тесты — как религия? Или? Они, вообще-то, средство, не цель.

То есть да, можно сделать этого код более модульным, более удобным для рефакторинга и прочее… Но это точно окупится? Человек, могущий менять конфиги у вас на сервере — и так, в общем-то, имеет над ним более-менее полный контроль… так зачем всё это дело обильно покрывать тестами и, скажем, фаззить? С чем боремся-то?
И там хорошо видно — у вас либо GOT, две инструкции и %rbx, либо одна инструкция, прямой доступ и %rip. То есть да — если у вас переменнай экспортируется из библиотеки, то доступ к ней будет через индирекцию — но и обычный регистр, не %rip

И кто занимается подстановкой правильных значений в GOT? Кто занимается подстановкой правильных значений перед %rip? К чему тогда было ваше исходное, что линкер или загрузчик этим не занимаются?

Из бинарника пропадают релокейшены. Правда-правда.

Я говорил о foo(%rip).

Ну это вопрос очень и очень философский. Глобальный флаг — быстрее. Передача в горячий код — медленнее, но более гибко.

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

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

Если в меня начинают бросаться всякими вумными словами типа «неSOLIDно», «нарушение инкапсуляции» и прочее, то я обычно останавливаю этот поток сознания и прошу снизойти до «простых смертных». И описать пример цепочки начиная с бизнес-требований.

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

Иначе — это архитектурная астронавтика какая-то.

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

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

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

Кто вам сказал, что читающего код здесь кто-то ненавидит? gethostbyname требует там '\0', а мы там имеем что-то другое… что такого странного в том, чтобы записать туда требуемый '\0', а потом вернуть всё «как было»?

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

Кстати, в kbd_gethostbyname есть обработка случая, когда длина строки больше или равна 128. Так что искомая проверка на 63 символа — это баг? Или тут должна быть не kbd_gethostbyname? Или тут может быть не только хостнейм? Или что вообще почему тут так?

А для вас тесты — как религия? Или? Они, вообще-то, средство, не цель.

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

Человек, могущий менять конфиги у вас на сервере — и так, в общем-то, имеет над ним более-менее полный контроль… так зачем всё это дело обильно покрывать тестами и, скажем, фаззить? С чем боремся-то?

Потому что кривая работа с памятью — это не только всегда свежие 0-day, но и ваш личный геморрой по отладке багов, проявляющихся через 10 вызовов функций, 10 секунд или 10 часов в совсем другом модуле. Спасибо, я этого в своё время наелся достаточно.
И кто занимается подстановкой правильных значений в GOT?
Динамический загрузчик во время запуска программы.

Кто занимается подстановкой правильных значений перед %rip?
Статический линкер во время сборки программы. В готовой программе, в бинарнике, там уже ничего не меняется никогда.

Из бинарника пропадают релокейшены. Правда-правда.
Я говорил о foo(%rip).
В бинарнике — это не релокейшен. Когда линкер из нескольких обьектных файлов делает бинарник там записывается фиксированное число, которое больше уже никогда не меняется. Что там было на этапе сборки программы — никого не волнует, мы же всё это обсуждаем в контексте влияния на скорость.

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

Соответственно, какая-то высокоуровневая обёртка над горячим кодом может решить, передать самому коду это как параметр, или выставить одному ему известную глобальную переменную, или ещё что сделать?
А это зачем? Пользователь программы может задать флаг, если хочет, а обёртке это зачем?

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

Изоляция систем и сужение интерфейсов между ними — естественное требование.
И вот тут, как раз, глобальные флаги — отличная вещь. Ибо когда «высокоуровневая обёртка над горячим кодом может [что-то там] решить» — это как раз и нарушает принцип изоляции.

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

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

Подход «флаги глобальны, читать их может кто угодно, но менять может только пользователь программы» — работает вполне надёжно. 3325 флагов у программы копирования файлов — никого особо не напрягают, так как все их мало кому приходится «дёргать» (думаю что практически — никому).

А всё потому, что чтение хостнейма и его валидация размазана что по kbd_gethostbyname (почему бы ей не передавать рейндж указатель на начало и конец строки, чёрт возьми?) и по вызывающей функции.
В С функции получают строку закрытую нулём. gethostbyname — не исключение. Можно было бы создать язык, где они принимали бы рейнджи… но это уже будет не C.

Кстати, в kbd_gethostbyname есть обработка случая, когда длина строки больше или равна 128. Так что искомая проверка на 63 символа — это баг? Или тут должна быть не kbd_gethostbyname? Или тут может быть не только хостнейм? Или что вообще почему тут так?
Можете посмотреть на код, однако. Или нет? kbd_gethostbyname запросы кеширует, но только для коротких (не более 128 символов) имён. Для длинных — пропускает как есть. Это механизм вообще не имеет никакого отношения к ограничению на 64 символа, которые приходят прямо из DNS'а. В главной программе допускаются только весьма ограниченное множество «правильных» имён хостов… хотя непонятно — зачем их на этом уровне-то проверять, когда gethostbyname(3) это сама должна сделать.

Потому что кривая работа с памятью — это не только всегда свежие 0-day, но и ваш личный геморрой по отладке багов, проявляющихся через 10 вызовов функций, 10 секунд или 10 часов в совсем другом модуле. Спасибо, я этого в своё время наелся достаточно.
Для этого Asan есть.

P.S. Вот, кстати, kdb_gethostbyname огорчила больше. В частности тем, что граница в 128 символов для кешированного имени выглядит какой-то абсолютно произвольной… и встречается в коде далеко не в одном месте. Тут уже и константу бы не грех сделать…
Динамический загрузчик во время запуска программы.

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

И чем это отличается от того, что я изначально сказал? Ну, кроме вышеупомянутой неаккуратности, конечно, но придираться к ней — перебор, ИМХО.


В бинарнике — это не релокейшен.

У нас снова терминологический спор :(


А это зачем? Пользователь программы может задать флаг, если хочет, а обёртке это зачем?

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


Не знаю, не знаю. У нас этим целые команды занимаются.

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


Ибо когда «высокоуровневая обёртка над горячим кодом может [что-то там] решить» — это как раз и нарушает принцип изоляции.

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


Подход «флаги глобальны, читать их может кто угодно, но менять может только пользователь программы» — работает вполне надёжно.

Конечно. У вас ведь компилятор гарантирует выполнение этого условия?


В С функции получают строку закрытую нулём. gethostbyname — не исключение. Можно было бы создать язык, где они принимали бы рейнджи… но это уже будет не C.

А, да, простите, я слишком в 2023, когда вся стандартная библиотека С++ переписана со string_view.


Можете посмотреть на код, однако.

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


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


И почему проверка на 128 символов ровно в ней? Да такая жёсткая, прям с ассертом?


И почему вообще эта проверка нужна, если, как вы написали выше, больше 64 символов оно быть не может?


И нет, не кеширует: последним параметром ip ей передаётся 0, а в этом случае вставки значения не происходит. Ну как там, код лёгкий, очевидный, ясно, что происходит?


Для этого Asan есть.

Успехов с асаном, когда RES за полсотни гигов, или когда лажа проявляется только под определёнными паттернами нагрузки, которые под асаном не воспроизводятся ввиду замедления.


Вот, кстати, kdb_gethostbyname огорчила больше.

Меня вообще весь этот код огорчает.

Тут не просто разница в терминологии. Тут разница во времени загрузки программы в память и во времени исполнения инструкций.

Да. Изначально речь вообще шла об индирекшнах вроде foo(%rip) и их влиянии.
Потому что о программах без глобального состояния проще

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

Вы слышали что-нибудь о вещах вроде MonadWriter?
А какое отношение MonadWriter имеет к системам логирования? Существует ли у MonadWriter файл конфигурации, по сложности сравнимый с конфигами семейства log4xxx и их наследников (logback, NLog)?

(Это был риторический вопрос, можете не рассказывать мне что такое MonadWriter)
Это дело десятое. Речь-то о подходе и о возможности избежать глобального состояния даже в этом случае.
Чем больше конфиг — тем дороже повторное чтение его каждый раз.
Зачем его читать много раз?

В конце концов, говоря на С++-ном, голая глобальная переменная и private static-поле — это ж две сильно разные вещи по возможным последствиям.
А что делать на Си, где нет приватных полей?
Задуматься о том, оправдан ли выбор С в данном случае.

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

Это относится к функциональным языкам — у них есть своя специфика, которая и позволяет обходить глобальные состояния… за счет глобальных монад. Да что уж, предлагаю пойти дальше — класс, функция — это тоже глобальный объект, в своем роде. Только вот их глобальность скрыта ЯП и не доступна, обычно, программисту. Хотя умельцы патчат классы в рантайме прямо в виртуалке при загрузке этих классов — AspectJ как пример.


И да, как решение для ликвидации глобального состояния — ФОП отличное решение.
А в остальных случаях как? Или идеализм и перфекционизм вездесущи и все строем должны идти учить хаскель?

Это относится к функциональным языкам — у них есть своя специфика, которая и позволяет обходить глобальные состояния… за счет глобальных монад.

Я не очень понимаю, что такое глобальная монада.

Или идеализм и перфекционизм вездесущи и все строем должны идти учить хаскель?

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

Ну и в конце концов, мы же тут об отличниках говорим?
«Зачем? Посмотрите где...»
Ну давайте посмотрим на «с».
c = *s;

Ок, пошли смотреть на «s»
char *ptr, *s;

Хорошо. Ищем инициализацию «s».
ptr = s = cfg_cur

Ура! Всё сразу понятно стало, сэкономленное на оформлении кода время окупилось, разработчику — премию (сарказм!).
Вот так и ходишь и смотришь большую часть времени, вместо того, чтобы просто читать понятный код.
Такое оформление, по которому нужно «Посмотрите где...» — это то же самое, что и «идите на...» по отношению к тому, кто в дальнейшем будет работать с кодом.
Пойдешь вот так, как Вы предлагаете, смотреть, что означает переменная "_suprknadel", а через полчаса обнаруживаешь 15 открытых модулей и еще больше вопросов.
Поубивал бы.
Извините за эмоции, но я только что вынырнул из модуля в 17000 строк, с которым работаю :(
А мне больше понравилось, как функция парсинга конфига заодно резолвит какие-то хостнеймы парой десятков строк ниже.
В когнитивной психологии ту часть памяти, в которой непосредственно производятся вычисления «в уме», называют кратковременной и рабочей. Там всё сложно и неоднозначно, но как её ни назови, а объём этой памяти сильно ограничен. Разные исследователи называют «магические числа» семь и пять. Это средние значения. Объём «рабочей» памяти зависит от обстоятельств и коррелирует с интеллектуальными способностями.

— Петька, приборы?
— 42.
— Что «42»?!
— А что «приборы»?

В каких единицах числа приведены? В битах? Байтах? Вариках?
Тут всё интересно. Пять и семь — это количество неких «объектов». Если заставить человека запоминать случайную последовательность букв, то такими объектами будут буквы, и человек запомнит в среднем примерно семь букв. А если слова — то примерно семь слов. А букв в этих словах будет существенно больше.
Однажды мне потребовалось запомнить последовательность из 3 иероглифов, чтобы через время их воспроизвести. Две минуты старался, но не осилил. При этом иероглифы были не сложными, до 5 штрихов каждый. Оказалось, проще было сфотографировать на телефон.

Это я к тому, что число объяснять надо. Вы говорите, что рассматривается случайная последовательность букв, но в тексте этого нет. Да и код отнюдь не случаен. Да даже для случайной последовательности следует указать размер алфавита «объектов» (7 букв запомнить — не 7 слов, что в свою очередь не 7 иероглифов).

P.S. я знаю про один эксперимент
На линейной шкале (оттенки серого, размеров и т.п.) выбирается в определённом смысле равноудалённо n точек и затем предлагается случайная последовательность этих точек человеку, чтобы он идентифицировал каждую точку. Шкалу он видит только единожды, перед началом классификации, число n знает. Оказало, наиболее комфортно человек классифицирует при n<9, причём эта цифра почти не зависит от природы линейной шкалы, лишь бы границы ощущались как диаметрально противоположные (белый-черный, точка-метр).
А Вы знали значение этих иероглифов? Если бы знали значение и знали наизусть их начертание — запомнили бы без труда. А так, задача запомнить произвольный набор из 10+ штрихов — непосильная для человека западной культуры. Это куда сложнее, чем запомнить 10+ произвольных букв.

А вот семь букв или семь слов (знакомых) для нас — это как раз всё равно. Потому что те и другие мы обрабатываем как целостные объекты, гештальты.
А Вы знали значение этих иероглифов?
Разве это существенно? Скажем, иероглифы хираганы я могу запомнить вряд до 15, если при восстановлении будет под рукой таблица, и до 7-10, если не будет. Китайские иероглифы даже в количестве 5 штук я не восстановлю, даже если под рукой будет соответствующая таблица. Значение ни тех, ни иных я не знаю. Просто алфавит меньше.
А вот семь букв или семь слов (знакомых) для нас — это как раз всё равно. Потому что те и другие мы обрабатываем как целостные объекты, гештальты.
Опять же. Что проще, запомнить «оывхзку» («о! ы-ы-ы-ы… вот хз… ку» — уже запомнил) и «овации пароходом гештальту пенсне шизофазия велюром седло»? Букв-то всего 33 и многовероятно появление слогов и других знакомых групп. А слов больше и далеко не каждое вызывает устойчивый запоминаемый образ.

Или же под объектом в тексте понимается именно образ? Но тогда как сделать однозначное сопоставления объекта и формальных языковых конструкций (букв, слов, словосочетаний)? У каждого же по-разному.
Опять же. Что проще, запомнить «оывхзку» («о! ы-ы-ы-ы… вот хз… ку» — уже запомнил) и «овации пароходом гештальту пенсне шизофазия велюром седло»?
Во втором случае очень много редких слов, а часть — явно распадается на два (шизофазия) или вообще не воспринимается как слово (гештальту). Если бы там не было таких ужасов — разницы бы не было.

А слов больше и далеко не каждое вызывает устойчивый запоминаемый образ.
Это да, некоторые слова будут занимать не один «обьект» в голове, а два или три.

Или же под объектом в тексте понимается именно образ? Но тогда как сделать однозначное сопоставления объекта и формальных языковых конструкций (букв, слов, словосочетаний)? У каждого же по-разному.
Именно поэтому мы не можем сказать точно сколько обьектов нужно держать в голове, чтобы осознать как работает функция. Можем только оценить.

Но можно заметить, что 5-7 обьектов — это столько, сколько мы можем «захватить» не напрягаясь. Если «загружать» в сознание обьекты постепенно и если это — не случайные, никак не связанные друг с другом обьекты, то можно уместить гораздо больше.

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

Знаки хираганы называются знаками хираганы (или знаками каны, если более обобщённо).

При этом эти знаки каны очевидно являются упрощениями все тех же китайских иероглифов

UFO landed and left these words here
UFO landed and left these words here

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

Резюме понравилось.
Любая индустриальная технология основана на расчётах, на возможности их проверки. Любой алгоритм должен давать простое понимание границ его применимости. Computing science должна быть доказательной и повторимой, как любая наука.

Как я написал выше, программирование как разработка программных систем это не только science, но ещё и art. Причём art как раз того порядка, про который мы пока только догадки строим: предсказания на основе непонятных внутренних эвристик. По сути, это как NP-задача, мы можем построить полиномиальные метрики к ней, но придумать полиномиальное решение, подходящее для всех, не можем, и даже не знаем, есть ли оно.
даже не знаем, есть ли оно.

Зато работа есть ;)
UFO landed and left these words here
Ну это одно из определений, в общем-то.
UFO landed and left these words here
Должна быть какая-то оптимальная компактность программного кода. Слишком сжатое изложение мысли трудно для восприятия из-за перегруженности смыслом, а слишком пространное — из-за большого объема. Как в задачке, с которой начиналась статья: подробное решение сложнее осмыслить и проверить, чем краткое. Но этот оптимум зависит от квалификации.
С гипотезой не согласен. С началом изучения действительно, бывало, писал длинные и запутанные портянки. На данный момент главная тенденция — удобочитаемость кода. Функции/процедуры/ и т.п стараюсь вместить на один экран, если допустимо. По длине строк — так же. Даже если объект более 1 раза не используется — ничего страшного. Главное — чтобы эти блоки были логически и мнемонически ясны тебе через месяц/год/и т.п. А если твой код смогут понять без труда другие программисты — то это она самая и есть — гениальность :))). И никакая оперативная мозговая память тут ни при чем.
А отличники пишут запутанный код 1) из-за спешки 2) Из-за неуважения к себе и другим
Это потому, что Вы наступили на достаточное количество граблей и перешли на следующий уровень. Опытный программист отличается от неопытного тем, что пишет понятный код.

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

Звучит примерно как: «Тестировать свой код — это для троечников. Зачем писать столько ненужного лишнего когда, если программа и так будет работать как-нибудь?» Ну… Чем не точка зрения, конечно.
Я тоже училась на все пятёрки и помню, какой это был понт, когда ты промежуточных вычислений не записываешь. Зачастую это приводило к ошибкам, которые трудно было отследить и исправить (что осложняло работу учителя в разы, как я поняла в дальнейшем, когда сама стала преподавать), но мы велись, и это всё счастье до сих пор живо в наших школах. Но мало ли на что школьники ещё ведутся: что курить — это круто, что если все пойдут с крыши прыгать…
Называть ли это всё «горем от ума»? Я бы, скорее, говорила о попытке самоутвердиться в своей социальной группе. У разных групп — свои критерии «крутизны», одними и теми же методами стать крутым вообще везде сложно (и это очевидно). А оценки — это просто оценки, они учителе-зависимые. Когда ты ещё ребёнок и не понимаешь, что оценивание твоей контрольной работы на 5 или 4 не имеет ничего общего с оценкой тебя, как человека, ты начинаешь за этой оценкой гоняться. А учителя — разные. Кто-то за многостраничную работу сразу ставит 5, не читая (ибо лень), а кто-то гарантированно снижает на балл-другой (потому что читать было лень, но всё равно пришлось).
Если ребёнку на уроках информатики начать снижать оценки за нечитабельный код, то через пару месяцев у «завзятого отличника» код станет самым читабельным в классе. Не думаю, что он от этого как-то резко поглупеет.
Школа она в любом случае и хорошо, что была, и хорошо, что была окончена. Если её выкинуть из головы, хуже не станет.
Вот бы и правда кто-то стал снижать оценки за нечитабельный код… Мечта…
хотелось бы познакомиться алгоритмом вычисления метрики когнитивный вес, очень очень, или вес это количество объектов?
Нет пока ещё такого алгоритма. Есть предположение, что, возможно, такая метрика может оказаться полезной. Что в неё следует включать — не до конца ясно. Объекты, которыми оперирует интеллект программиста при написании участка кода. Ясно, что какими объектами он оперирует, те и пишет в код. Но какие именно объекты? Переменные, вызовы методов, операции, константы, элементы структур — что? Какие именно из этих объектов занимают место в рабочей памяти программиста, а какие — нет? Проблема очерчена — есть, над чем поработать.

Почитайте «Программный код и его метрики», и особенно метрики Холстеда. Там много пищи для размышления.
имхо берёшь AST кода, задаёшь каждому узлу ( не только листу, но и ветке включая внутренние узлы) тэг классификации по смыслу, то есть «в этом цикле считается количество домов в городе» а не «в этом цикле переменная и увеличивается от 0 до 1000», определяешь метрики= расстояние между смыслами.
А всякие количественные метрики это ерунда — ту же самую программу можно переписать в другом виде чтоб весь тот расчёт был другой, то есть он не репрезентативен.
Нет пока ещё такого алгоритма

Думаю, и не будет. По крайней мере — одного для всех.


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


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


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

Хорошая тема, очень правильная и актуальная.

До сих пор помню один из самых обидных фейлов в жизни.
На одной из пар (насколько помню, по диффурам) была задача, что-то там про пулю, которая врезается в крутящийся барабан. Решил её раньше всех – сразу было ясно, что всё решается методами простейшей физики и геометрии, тупо школьный курс же.
Но получил «трояк». Ибо препод решил, что «не по уставу». Даже несмотря на то, что ответ полностью сошёлся с ответами горе-отличников, корпевших над «уставным» решением чуть ли не вдвое дольше…

Мораль сей басни такова – хорош не тот, кто просто зубрит, а тот, кто понимает предмет в целом и суть конкретного вопроса в частности. И на оценки тут уже плевать – они важны только лишь в узких рамках ВУЗа, а дальше жизнь сама расставит всё и всех по своим местам… ;)

P.S. Хорошо, что хоть по информатике нам достался хоть и «советски»-отсталый, но крайне здравый преподаватель – «неуставные» решения не рубил и не критиковал, а сам приходил от них в восторг. До сих пор вспоминаю его с искренней теплотой… ^_^

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

увидеть задачу для себя

Вот именно об этом я и говорил.
Образ мышления отличника – решить всё «правильно, как учили». Образ мышления программиста – решить всё максимально рационально, пусть даже это будет «не канонично». Иначе говоря, «труъ-программистское решение» – найти путь к тому же (!) результату, но меньшими усилиями и меньшей тратой ресурсов. Оптимизация же, и всё такое (о чём, кстати, вообще и статья)…

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

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


Ваш вариант — это в соревновании бега в мешках пробить в нем дно и бежать.
Решение не подпадает под заданную цель. Считайте это как ТЗ.


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


Где же в вашем первоначальном комментарии "правильно, как учили"?

Решение не подпадает под заданную цель. Считайте это как ТЗ.

ИМХО, для программиста заданная цель – не конкретные методы решения, а решение в целом. Оно и является настоящим ТЗ (если только, конечно, ограничения в методах не вызваны объективными причинами).
дифуры — это микроскопом гвозди забивать, когда есть более простое и доступное решение.

Вот, оно самое, о том и речь!
Это и есть «образ мышления настоящего программиста». Что также во многом зависит и от методов обучения, кстати. Если учили думать – ищи методы оптимизации. Если учили решать «в лоб», «только как положено» – забивай гвозди микроскопом и прочими не предназначенными для этого гаджетами.

Ведь настоящая цель программиста не просто «решить и проставить галочку» (это как раз пресловутая «проблема отличника», описанная в статье).
Настоящая цель – решить оптимально! Чтобы потом не получались тонны «индусского кода» даже в простых проектах (что как раз схоже с решением той приведённой мной ранее задачи – моё было в несколько строчек, «оригинальное» в несколько раз длиннее)…
> Настоящая цель – решить оптимально!

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

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

А разве кто-то говорил, что одно исключает другое? Вовсе ведь нет – никто не призывает отказываться от навыков составления диффуров.
Говорилось о том, что важно понимать, какие конкретно методы наиболее оптимально использовать конкретно в этой в поставленной задаче. Если диффуры – то диффуры, если простая геометрия+арифметика – значит, именно их.

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

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

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

Согласен, порой оптимизация может отнять больше времени, чем «лобовой» вариант. И проще выбрать «в лоб». Но принятие такого решения – тоже есть в своём роде оптимизация. Как минимум, по времени разработки.

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

Так "по умолчанию" означает, что разработчику принимать решение не нужно, оно уже принято за него.

Не вполне понял, почему это адресовано мне. Но отвечу…

Хороший разработчик тем и отличается от «масс-кодера», что способен поспорить за действительно правильное решение. Иначе говоря – ему НЕ плевать на результат работы, он не просто пассивный исполнитель из серии «любая тупость за ваши деньги».
Да и вообще, собственно, это касается настоящих профессионалов в совершенно любых областях, не только айтишных.

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

P.S. При этом вновь оговорюсь, что даже в этом благом деле нужен разумный баланс между реальными обоснованными замечаниями к ТЗ и собственными амбициями. Иначе, с другой стороны, получается не профессионал, а просто скандалист-социофоб с манией величия… ))

Потому что:


по умолчанию надо выбирать "в лоб"

Но принятие такого решения – тоже есть в своём роде оптимизация.

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

Не очень понятно о чём вы спорите. Для разработчика — во многих случаях «лобовое» решение — правильный выбор. Для ученика — нет.

Потому что первому таки-надо решить задачу. Второму-таки нужно научиться определённым приёмам.
Для разработчика — во многих случаях «лобовое» решение — правильный выбор.

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

Во-первых, речь не только о скорости исполнения, но и о скорости разработки…
А) Три дня мудохаться, писать «линейный» код. После каждого исправления переписывать большую часть.
Б) Один день подумать, ещё за день написать чётко структурированный код, в котором всё строится всего на паре-тройке ключевых параметров. Исправления делаются за несколько минут.

В первом случае – решение «в лоб».
Во втором – та самая оптимизация.

Недавно как раз был такой веб-проект. Нанятые разрабы писали всё сразу «набело» (то бишь, «в лоб») – в итоге чего каждое исправление/комментарий вылетали минимум в день-два (а то и больше) полного переписывания всех функций, плюс полной отладки заново. Просто вот их так научили – не думать, сразу писать.
После всей ругачки и «поучений» (кряхтя, вспомнил все азы) – таки добились того, что теперь в проекте любые исправления обрабатываются максимум за пару-тройку часов. За счёт той самой оптимизации кода, да…

И в каком варианте в итоге получилась бОльшая скорость разработки, как вы считаете?

Я не зря упомянул про разносрочные перспективы.

Да здесь даже почти независимо от перспектив…

ИМХО – разработчик сразу (!) должен писать так, чтобы быть готовым к любым возможным исправлениям. То есть – сначала продуманная структура, только потом код.
Тем более, что ему же самому придётся нереально мудохаться, случись вдруг какие действительно серьёзные исправления. Если даже не «профессионализьму ради» – так хоть ради собственного комфорта…

P.S. Не зря ведь есть старинная пословица: «Семь раз отмерь, один отрежь». ;)

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


  • стоимость подготовки
  • стоимость внесения изменений при условии подготовки
  • стоимость внесения изменений при условии отсутствия подготовки
  • вероятность появления необходимости внесения изменений
Тут всё проще… )

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

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

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

стоимость

Кстати, мимо…
Стоимость как раз проще всего накручивать на «тупо-работах» – вроде переделок и прочего описанного выше. И, в любом случае – вашу зарплату это никак не поднимет, всю пенку снимет работодатель…

Предвидеть, что может измениться — это уровень понимания бизнеса, а не проекта.

Предвидеть, что может измениться — это уровень понимания бизнеса, а не проекта.

Не вполне согласен.
Чаще всего – это либо проблемы всё того же написания ТЗ, либо проблемы понимания разработчика.

Если первый вариант – спорьте с ТЗ и/или дополняйте его собственным видением проекта.
Если второй вариант – надо расширять кругозор. Да, как ни странно, но программирование – это не только про код. Это про как раз про понимание сути задачи – на основе коего понимания и пишется нужный код…
Есть подозрение что это обычная ситуация, когда у программистов есть понимание бизнеса, понятно не идеальное, но достаточное.
> Вовсе ведь нет – никто не призывает отказываться от навыков составления диффуров.

А откуда они возьмутся, если человек упорно сачкует вместо того, чтобы их развивать?

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

В поставленной задаче требовалось сформулировать и решить диффур. Если автор может сформулировать и решить диффур как-то хитро — да ради бога. Но он ведь в итоге решил совсем другую задачу.

> Те самые «шоры» просто помешали им сразу же понять, что в этой задаче вообще нечего городить диффуры.

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

Странно вы называете поиск оптимального решения «сачкованием». Результат ровно тот же самый. Времени – намного меньше. Расскажите, пожалуйста, почему это «сачкование»? )))
Но он ведь в итоге решил совсем другую задачу.

Нет, не другую, а ровно ту же самую. Но совершенно другими методами, более сложными. А другой пришёл к цели более простыми методами, да ещё и за меньшее время. Тут в теме уже проскакивало про «забивание гвоздей микроскопом» – так вот это самое оно… )))
Использование другого навыка — обычный читинг

Использование реальных навыков «читингом» не может быть просто по определению. Это и есть верное и самое кратчайшее решение задачи. Без обмана, без подсказок (что и есть читинг)…
Возражения будут?
> Расскажите, пожалуйста, почему это «сачкование»? )))

Потому что человек занимается бесполезными вещами вместо выполнения упражнения.

> Нет, не другую, а ровно ту же самую.

Нет, другую. Задача была — прокачать навык написания и решения диффуров.

> Без обмана, без подсказок (что и есть читинг)…

Читинг — это не обман и подсказки, а просто неверное выполнение упражнения. Которое не дает никакой пользы. Что вам непонятно в примере с использованием калькулятора вместо того, чтобы учиться считать в столбик? Вы ведь честно и без обмана получаете ответ. Быстро и оптимизировано. И прокачиваете навык владения калькулятором (который, в принципе-то, может быть и полезнее, чем умение считать в столбик). Только, думаю, вы не станете спорить что о верном выполнении упражнения здесь речь не идет? Несмотря на то, что вы получили правильный ответ.
бесполезными вещами

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

> Упражнение, выполняемое неправильно, в лучшем случае — бесполезно, а в худшем — вредно!

А вот мой ответ на ваш совет…
Мы сейчас говорим о реальной практике – в которой критически важно не верное выполнение, а верное решение. Суть вещи разные.

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

Ведь стать отличником можно двумя путями:
  • Первый путь, самый лёгкий – усердно зубрить и следовать строго в русле учебной программы, без малейших сомнений в возможности ошибок курса и/или его преподавателей.
    Они решают исключительно задачу получения оценки.
  • Второй путь, более сложный – пытаться действительно разобраться и «глубинно» понять самому. Стать лучшим не только в оценках, но и в практике применения полученных знаний.
    Они решают задачу получения реальных знаний и навыков.


Первых, увы – абсолютное большинство. Именно о них и статья – к большинству задач они подходят «как трамвай по рельсам», используя знания достаточно пассивно, «в режиме read-only». Вторых намного меньше, но именно они и становятся действительно хорошими специалистами, настоящими мастерами своего дела, используя знания активно и сами их дополняя «в режиме read-write»…

P.S. Просто сам имею немалый опыт руководящей работы, от начальника отдела до работодателя – поэтому давно понял, что никакой красный диплом сам по себе не является гарантией того, что перед тобой действительно хороший специалист.
Реальный профессионализм познаётся только лишь на практике – и вот тут, к сожалению, у многих бывших отличников как раз и начинается та самая беда, о которой и говорится в статье, в общем-то…
> Мы сейчас говорим о реальной практике – в которой критически важно не верное выполнение, а верное решение.

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

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

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

ИМХО, это уже само по себе неправильно.
Как уже писал – преподаватель имел все шансы на этом примере провести отдельный (и крайне полезный!!!) «мини-ликбез» аудитории на тему того, как искать кратчайшее решение. Пусть даже это и не было в рамках его предмета, но как специалист он был обязан объяснить это будущим специалистам.
Если, конечно, специалисты интересны ему не только лишь в рамках своего предмета (что неправильно), а в целом (что правильно)…

P.S. Упражнения «на составление», насколько помню, всегда были лишены конкретики. А если требовался конкретный числовой ответ при вводных параметрах – следовательно, была именно задача, и именно «на решение». Даже ответы в конце задачника были одним значением…
Первые пропустили явно спорную задачу, а второй этого не заметил и дал её аудитории – после чего даже не признал «спорности вопроса»…
Не бывает задач, которые могут быть решены только одним способом.

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

Это не значит, что все другие методы не имеют смысла.

Даже ответы в конце задачника были одним значением…
Именно поэтому учитель не появляется на 5 мин в начале урока со списков задач, которые нужно решить, а общается с учениками все 45 минут.
Не бывает задач, которые могут быть решены только одним способом.

Разумеется. Но для программиста-то критически важно нахождение кратчайшего и наиболее оптимального решения (как раз вот чуть ниже обсуждали этот момент с автором).
Поэтому ладно ещё труъ-математикам, но давать студентам ПМП подобные задачи «с двойным дном» – нууу… как-то странно, что ли, как минимум…
> Первые пропустили явно спорную задачу, а второй этого не заметил и дал её аудитории – после чего даже не признал «спорности вопроса»…

О какой спорности задачи речь идет? Это была вполне конкретная задача на диффуры в курсе диффуров, про которую преподаватель сказал, что она о диффурах.

> что из двадцати человек «подвох» заметил только один

В чем подвох-то?

> P.S. Упражнения «на составление», насколько помню, всегда были лишены конкретики.

Сформулируйте хоть _одну_ задачу на составление диффура без конкретики.
О какой спорности задачи речь идет?
В чем подвох-то?

Подвох в том, что предлагалось решать сложнее и дольше то, что можно решить гораздо проще и короче. Думал, этот момент очевиден…
Сформулируйте хоть _одну_ задачу на составление диффура без конкретики.

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

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

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

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

Миль пардон, но что за ересь???
Любое упражнение направлено на отработку определённых навыков. Если упражнение не отрабатывает веру в полезность этих навыков, не заставляет учащихся искренне поверить в силу предмета, а лишь симулирует данную полезность – тогда просто в топку такое упражнение! Оно не породит в учащихся ничего, кроме уверенности в том, что им «пихают какую-то бесполезную хрень»…
Об этом ведь речь.
А в чем проблема предложить студенту сразу и решить уравнение, раз уж он его составил?

Эээмм… Простите, а вы действительно имели дело с задачами по диффурам? Или просто путаете определения «решить» и «привести к требуемому виду»?
> Миль пардон, но что за ересь???

Это не ересь, это суровая правда жизни. Обучение заключается в преодолении трудностей. Человек получает навык тогда, когда делает то, что ему сложно делать. Когда он делает то, что делать просто, то и навыков никаких не прокачивается. No pain — no gain.

> Оно не породит в учащихся ничего, кроме уверенности в том, что им «пихают какую-то бесполезную хрень»…

Оно породит навык использования конкретного метода. Это то, что оно должно порождать. Заинтересовывать учащегося и доказывать полезность навыка от учебного процесса не требуется. Не интересно — нахер с пляжу. Пусть место займет тот, кому интересно.

> Или просто путаете определения «решить» и «привести к требуемому виду»?

Мы везде обсуждали — «составить и решить». Никто ничего не путает.
Обучение заключается в преодолении трудностей.

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

Хммм… Я вот сейчас даже как-то затрудняюсь прокомментировать этот «труъ-армейский» тезис без ненормативной лексики…
Возможно, именно в подобном подходе и есть все первопричины нынешнего достаточно бедственного уровня образования?..
Мы везде обсуждали — «составить и решить»

Мы везде в теме, с самого начала, обсуждали принципы решения «труъ-отличника» и программиста. Как уже говорил, для первого важно соответствие «ТЗ», а для второго важен исключительно результат – на чём и выводилась разница между этими совершенно разными подходами…
> Но трудностей реальных, а не выдуманных.

Так никто и не говорил о выдуманных трудностях, откуда вы их взяли?

> Возможно, именно в подобном подходе и есть все первопричины нынешнего достаточно бедственного уровня образования?..

Так нету никакого такого подхода. Сейчас преподаватели не то что в школе, а даже и в университете прыгают вокруг студентов как дрессированные обезьянки в надежде на то, что дитятко сделает одолжение и испьет знаний из кувшина их мудрости. Так, конечно, быть не должно. Мотивировать на учебу должны родители, идеология, общество, но никак не само учебное заведение. Так это было, например, в союзе. В учебном заведении должны учить. Если человек перешагнул порог учебного заведения, то должно считаться, что он заведомо мотивирован и пришел учиться. А если нет — пошел вон. Зачем учить человека, который учиться не хочет? Лучше направить свои силы на того, кто хочет. Это просто более эффективно.

> а для второго важен исключительно результат

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

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

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

Немного не так.
Вы, конечно, можете сказать, что у меня какие-то слишком уж возвышенные представления… Но талант настоящего Преподавателя-С-Большой-Буквы в том и состоит, чтобы не просто тупо отбарабанить свой курс в воздух аудитории – а именно «зажечь» студентов своим предметом. И от таких преподавателей чаще всего и выходят будущие профессионалы, а не просто «прослушавшие курс».
А самомотивация – оно, конечно, отлично и приятно. Но, во-первых, априори доступна не всем. А во-вторых – уж тем более не в таком юном возрасте (когда полно гораздо более заманчивых искушений))…

Вот и получается старинная дилемма, из серии всяких там про государство и граждан. У вас – «студент для ВУЗа». У меня – «ВУЗ для студента».
«Программист» же решил, что он не хочет добиваться результата, а хочет фыр-фыр-фыр.

Не так. Программист увидел, что ему подсунули «дутую» проблему – и решил её оптимально. В этом и есть вся «труъшность» подобного решения.
А что важнее всего – запросто мог бы решить и «как положено», «как отличник». Но это заняло бы намного больше времени.
Ну и где тут «фыр-фыр-фыр»? )))
> Если простую задачу предлагают решить более сложным методом – это выдуманная трудность.

В чем выдуманность? Трудность вполне реальная.

> Но талант настоящего Преподавателя-С-Большой-Буквы в том и состоит, чтобы не просто тупо отбарабанить свой курс в воздух аудитории – а именно «зажечь» студентов своим предметом.

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

> А во-вторых – уж тем более не в таком юном возрасте (когда полно гораздо более заманчивых искушений)

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

> Не так. Программист увидел, что ему подсунули «дутую» проблему – и решил её оптимально.

Никакой дутости. Ему подсунули проблему отработки навыка составления и решения диффуров. Он данную проблему не решил. Ни оптимально, ни неоптимально — вообще в принципе никак не решил.

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

> А что важнее всего – запросто мог бы решить и «как положено», «как отличник».

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

В наличии заведомо более простого решения.
Если студент пришел на лекцию — он по умолчанию считается «заженным».

Ох, вот тут вы категорически ошибаетесь, вновь применяя тот же подход, где «галочка» важнее всего. Студент либо «горит» предметом, либо нет. Нет тут никакого «по умолчанию», и быть не может – этот момент не решается «в явочном порядке»!

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

Пока существует культ диплома вместо реальных знаний – никто не придёт. Либо будут учиться сами, уже не у вас.
Ему подсунули проблему отработки навыка составления и решения диффуров.

Ранее уже отвечал на эту тему. Но могу ещё раз, уже иначе…
Программист и должен первым делом видеть задачу, понимать её в самой сути. Условно говоря, если предлагают вкручивать саморезы пилкой для ногтей или пилить ногти отвёрткой – программист должен первым сообразить, что это неправильно и должно быть «как-то наоборот», мягко говоря…
Потому что ленивый (и не факт, что вообще смог бы, он ведь плохо учится). В итоге он хуже как специалист.

Согласен, ленивый. Лень решать долго то, что можно решить быстро. Хороший программист должен ценить своё время – что и толкает на оптимизации.
Тут самое место для знаменитой цитаты дядюшки Гейтса о ленивых – надеюсь, вы с ней знакомы. А если нет, то самое время познакомиться – это вот оно самое и есть… ;)))
> В наличии заведомо более простого решения.

А выдуманность в чем?

> Ох, вот тут вы категорически ошибаетесь, вновь применяя тот же подход, где «галочка» важнее всего.

Галочки не важны, важны эффективные решения. Обучение того, кто учиться не хочет — неэффективно.

> Студенты приходят на лекцию порой лишь ради того, чтобы не проставили пропуск.

Таких студентов следует отчислять, а не «зажигать» или что там еще.

> Программист и должен первым делом видеть задачу, понимать её в самой сути.

Итак, задача, ее суть — составить и решить диффур. Четко, ясно, однозначно. Никаких непоняток. Студент задачу решил? Не решил. Какие еще могут быть вопросы?

> Согласен, ленивый. Лень решать долго то, что можно решить быстро.

Но студент не решил задачу. Из-за своей лени он вместо нужной, полезной задачи, которую его требовали решить, решил другую — бесполезную. И на работе он будет делать точно так же.
Таких студентов следует отчислять, а не «зажигать» или что там еще.

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

Человек знает и умеет только то, что ему показали и рассказали другие люди. Если людей вокруг не было, то вырастают Маугли. Не надо сразу отчислять, этих «Маугли» и так слишком много вокруг нас. Будьте гуманнее. Студентам, которые ходят на лекции ради галочки, просто не встретился Человек, с которого они захотели бы брать пример. Они видели вокруг лишь преподавателей, которые тоже ходят на лекцию ради галочки. В Москву с рыбным обозом приходят единицы.
> Если людей вокруг не было, то вырастают Маугли.

Я же и не говорю, что не надо этим заниматься в принципе. Надо, только не учебному заведению. Человек должен идти в университет тогда, когда он знает «я хочу научиться Х». Это должно быть четким, осознанным желанием. Иначе он пойдет на специальность, которая ему не нужна и будет учиться там тому, что не любит. И «зажигающий преподаватель» тут только скрасит процесс, как таблетка обезболивающего. Но не решит проблему прогрессирующего рака в целом.

> Студентам, которые ходят на лекции ради галочки, просто не встретился Человек, с которого они захотели бы брать пример.

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

Да нет же!!!
Вы зачем-то сразу ориентируетесь на заведомых «случайных студентов» – которых априори подавляющее меньшинство. И только лишь на основании самого факта наличия таких – вы призываете всех (!!!) преподавателей «не париться и тупо-нудно читать курс».
Если руководствоваться исключительно подобными принципами – то и будет продолжаться нынешний регресс вместо прогресса.

А вы просто попробуйте читать курс так, словно вся аудитория – хорошие студенты! Читайте именно для них, для таких! И насрать на остальной «балласт». Просто делайте свою работу хорошо.
Тогда, более чем вероятно – выявятся даже и «скрытые таланты». И даже там, где вы и не ожидали…
> Вы зачем-то сразу ориентируетесь на заведомых «случайных студентов»

С чего бы?

> И насрать на остальной «балласт».

На балласт не насрать, потому что этот баланс — объективно неэффективное использование средств. Балласт следует сбрасывать, в первую очередь — ради самого балласта. Если человек не хочет учиться на Х, то ему следует попробовать идти учиться на кого-то другого, чья деятельность ближе душе, а не скакать вокруг, завлекая разными интересностями.

> Тогда, более чем вероятно – выявятся даже и «скрытые таланты».

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

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

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

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

Если же вокруг меня «гореть» никто не будет, то и у меня повода задуматься о перемене места просто не будет: какой смысл менять шило на мыло, если вокруг один мрак беспросветный и безнадёга, хоть здесь, хоть везде. Отучусь-ка я здесь как-нибудь…

А искусственных трудностей — не надо, у нас и натуральных хватает.
> По-моему, Вы утрируете. Никто никого не веселит и не развлекает.

Это то, чего требует от преподавателя Garruz. Чтобы учебный процесс для студента был классный и веселый даже в том случае, если он студенту нахрен не нужен.

> Если же вокруг меня «гореть» никто не будет

Вы опять выводите проблему во вне. Хочет человек или нет заниматься Х — зависит _исключительно от этого человека_. Но никак не от преподавателя по диффурам. Хотите вы быть программистом — значит хотите, не хотите — значит не хотите. Если не хотите — следует вас отчислить ради вас же, чтобы вы пошли туда, куда хотите.

Цель обучения — не в процессе, она в том, чтобы потом использовать полученные навыки. Если у вас есть желание использовать эти навыки — вы будете вкалывать ради того, чтобы их получить. Если нету такого желания — не будете. Сама привлекательность процесса получения навыка — сугубо вторична, это просто труд. Его не требуется делать интересным или веселым, точно так же, как работодатель не обязан делать потом интересной и веселой вашу работу.
Все-таки говорить что дело только в человеке тоже не вполне правильно. Преподаватель должен не отбивать желание изучать предмет.
> Преподаватель должен не отбивать желание изучать предмет.

Вы уводите фокус в сторону. Желание изучать предмет ученику _вообще не требуется_. Оно лишнее. Если человек хочет получить какие-то навыки, то он будет изучать соответствующие предметы, даже в том случае, если процесс ему активно неприятен.

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

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

Попытка «скрасить» неприятные процессы не приводит ни к чему кроме того, что этот навык атрофируется. В результате получается не человек, а безвольный кусок мяса.
Это вредит в первую очередь самим студентам — вместо того, чтобы спустя полгода свалить на другую специальность, он просидит, отучится 5 лет, получит диплом, и дальше будет работать на ненавистной работе (или не по специальности, в результате чего те 5 лет окажутся просто тратой времени).

  1. Работая на ненавистной работе он будет приносить пользу как себе (зарплата, статус), так и обществу в лице работодателя( раз уж платит зарплату)


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

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

Да всё с того бы – если перечитать все ваши предыдущие сентенции…
Балласт следует сбрасывать, в первую очередь — ради самого балласта.

Нередко кажущийся «балласт» на поверку оказывается вовсе даже не «балластом» – как раз если правильно «зажечь»…
Опять же, выявление талантов — никак не задача учебного заведения, по крайней мере, не задача во время учебного процесса (во время приема, быть может). Вместо того, чтобы какими-то окольными путями пробуждать в человеке интерес, следует его отчислить и направить куда-то в иное место.

Это вот просто роковой способ мышления для любого настоящего (!!!) преподавателя.
Преподаватель должен работать с тем, что есть здесь и сейчас. Других студентов ему никто не даст. Поэтому и должен вытягивать максимум именно из этих студентов – вместо того, чтобы как-то там сортировать их по неким «критериям годности» на своё собственное усмотрение.
Соответственно – и работать всегда должен «как для самых лучших». Иначе это ни хрена не настоящий Учитель, а просто тупая штатная единица, ИМХО…
> Да всё с того бы – если перечитать все ваши предыдущие сентенции…

Очевидно, вы невнимательно читали. Перечитайте еще раз.

> Нередко кажущийся «балласт» на поверку оказывается вовсе даже не «балластом» – как раз если правильно «зажечь»…

Зачем вредить человеку?

> Преподаватель должен работать с тем, что есть здесь и сейчас. Других студентов ему никто не даст.

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

> Соответственно – и работать всегда должен «как для самых лучших».

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

Я перечитывал. Поэтому аналогичный совет…
Зачем вредить человеку?

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

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

Но это и есть одна из главных задач настоящего Преподавателя – всегда пытаться вытянуть максимум из всех, а не только лишь из самых способных…
Понятно, конечно, что «максимумы» будут разными, в зависимости от конкретного студента – но хоть реально максимумы, а не просто «сброс в утиль»…
> Вредить??? Поясните этот момент, будьте добры…

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

> А вот как раз это уже и есть просто потакание всем слабостям.

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

> даже без малейших попыток «перевоспитания» в какую-либо сторону.

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

Зачем пытаться делать из человека того, кем он ну никак не хочет быть?

> Но это и есть одна из главных задач настоящего Преподавателя – всегда пытаться вытянуть максимум из всех, а не только лишь из самых способных…

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

Не склонять – заинтересовывать. Вспомните хоть классический забор Тома Сойера. Что это, если не грамотная мотивация? )))
Наоборот, потакать слабостям предлагаете вы.

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

В том, чтобы вовлечь в тему как можно больше активных учащихся, даже «спящих». А там уж, кто знает – вполне возможно, что и полностью переключатся в это русло. А если даже и нет – то хотя бы знать предмет будут точно хорошо.
Таким образом, хороший «промоушн» своего предмета – одна из первостепенных задач хорошего университетского преподавателя.
Если человек не хочет учиться рисовать, а хочет вскрывать лягушек — то задача настоящего Преподавателя по изобразительному искусству сдать такого человека с рук на руки настоящему Преподавателю по медицине.

Немного не так. Точнее – так, но лишь в идеале.
Если человек оказался уже здесь и сейчас, конкретно на этом курсе – вы не сможете его никуда «передать». Но вы, как преподаватель, обязаны сделать всё от вас зависящее, чтобы дать человеку максимальные шансы проникнуться вашим предметом.
Да, не факт, что получится именно с ним. Зато получится с остальыми.
> Немного не так. Точнее – так, но лишь в идеале.
Если человек оказался уже здесь и сейчас, конкретно на этом курсе – вы не сможете его никуда «передать».

Конечно, сможете. Отчисляете — и у него нету никакого иного выбора, кроме как «передаться». Ну, либо можете его развлекать вместо обучения, только толку?
А если вы отчислили потенциального отличного специалиста по вашему предмету?
Ведь его реальные данные не обуславливаются только лишь посещаемостью ваших лекций. Может быть и так, что у него просто некая «аллергия» конкретно на ваши методы преподавания…

Понимаете, тут самый главный затык именно в том, что ваша задача как преподавателя – не «сортировать» студентов, а пытаться сделать специалиста из каждого. Получится не с каждым, да. Но пытаться вы обязаны именно с каждым, пока не получится.
> А если вы отчислили потенциального отличного специалиста по вашему предмету?

Такого быть не может. Отличный специалист не получится из того, кто не хочет учиться.

> Понимаете, тут самый главный затык именно в том, что ваша задача как преподавателя – не «сортировать» студентов

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

Такого быть не может. Отличный специалист не получится из того, кто не хочет учиться.

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

Вопросы вида «почему человек хочет стать космонавтом, а не балериной» особого смысла не имеют. Так воспитали. Это данность.

> Возможно потому что вместо понимания зубрежка требуется?

При чем тут понимание и зубрежка? Еще раз — мы не говорим о желании учиться. Желания учиться быть и не должно, это все лишнее. Должно быть желание _научиться_. Если человек хочет научиться — он будет превозмогать, даже если ему учиться не нравится.
Воспитание не заканчивается в детстве. Возможно это со мной что то не то, но по моим ощущениям у меня переходный период закончился курсу к третьему, четвертому, как и формирование интересов, вкусов, характера и т.п… Что касается желания учиться или научиться — во втором случае приходиться себя заставлять, тратить волевые усилия, морально уставать, а в первом можно учиться и получать удовольствие именно от этого. Таким образом учиться становится гораздо проще.
> но по моим ощущениям у меня переходный период закончился курсу к третьему, четвертому, как и формирование интересов, вкусов, характера и т.п…

Вот тогда и надо учиться.

> Что касается желания учиться или научиться — во втором случае приходиться себя заставлять, тратить волевые усилия, морально уставать

Конечно. Без этого никакого обучения и не бывает. Это всегда труд и страдания, иначе и результата нет.

> Таким образом учиться становится гораздо проще.

И результат, конечно же, становится на порядок хуже.

Это уже не говоря о том, что факт преодоления трудностей при обучении полезен сам по себе.
У меня ощущение что вы из тех кто считает что нужно страдать. На учебе страдать, работа тоже не может быть в удовольствие. Да и вообще в жизни нужно страдать. Но ведь это не так, можно жить, учиться и работать в удовольствие. Если же вы испытываете от всего этого мучения, то как бы банально и пафосно это не прозвучало — возможно вы делаете что то не так?
> У меня ощущение что вы из тех кто считает что нужно страдать. На учебе страдать, работа тоже не может быть в удовольствие.

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

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

Не контроль «знаний», а контроль способностей.
В этой короткой фразе – вся суть глобальной разницы между вашей и моей точками зрения…
> Из того, кто не хочет учиться вообще?

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

> Или из того, кто не хочет учиться конкретно по вашим методам

Ради бога, пусть учится по другим.

> Не контроль «знаний», а контроль способностей.

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

Согласен. Но говорим-то мы совершенно о другом – о слепом следовании предложенной методике…
Ради бога, пусть учится по другим.

Да, но преподаватель-то у него вы – который считает любой отход от своей программы «жуткой крамолой» и не оценивает любые альтернативные варианты решений.
И что делать студенту, если преподаватель – вы? Менять ВУЗ? Или подстраиваться под вашу программу, хотя он способен на большее?

Поэтому если такой студент бросит ваш курс – в этом будет ваша и только ваша вина. Это будет означать, что именно вы не смогли увлечь и раскрыть потенциально хорошего специалиста.
А в чем смысл контроля способностей? Это то, на что преподаватель повлиять не может, обратной связи нет. Бессмысленная задача.

Хм…
Вы правда настолько искажённо представляете себе задачу Настоящего Учителя? Неужели вообще нет опыта в этом, неужели даже отработку на преподавании не проходили?..
Настоящий Учитель всегда работает в режиме диалога, а не монолога.
> Да, но преподаватель-то у него вы – который считает любой отход от своей программы «жуткой крамолой» и не оценивает любые альтернативные варианты решений.

Вы что-то уже совсем свое выдумываете. Никто не говорил про отходы от программы, речь шла о том, что студент просто не выполняет задания. В принципе. Ему дали задание — он его не выполнил из-за лени. Конец истории.

> Настоящий Учитель всегда работает в режиме диалога, а не монолога.

И при чем тут способности, на которые Учитель не может повлиять?

> Вот потому у нас и едва ли не полстраны таких «горе-специалистов» (от программистов до преподавателей) – которые учились ради корочек и должностей, а не ради знаний…

Вы как будто не то читаете. «стать специалистом» — как раз предполагает наличие знаний, а не корочки.

> Человек должен «гореть» своей работой. И «зажечь» его – задача именно преподавателя.

Человек идет учиться, если горит работой. Если он работой не горит — ему не надо учиться на эту профессию, надо искать, от чего он горит. Потому что если человек от чего-то не горит — он и не загорится. Вне зависимости от преподавателя.

> Речь не о «свободной мысли». Речь о Мысли Вообще – которая выше любых статичных методик.

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

> А если вы преподаватель – то вы просто обязаны хотя бы пытаться.

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

Не «из-за лени» – а из-за наличия более разумного и быстрого (!) решения. Разницу видите?
И при чем тут способности, на которые Учитель не может повлиять?

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

Увы, нет…
Звание «специалиста» (тут в кавычках) и реальный специалист – совершенно разные сущности.
Множество глупых контор до сих пор набирают себе сотрудников исключительно по «корочкам». Это тупо слепая калька с западных манер. Но там «у них» это объясняется тем, что красный диплом реально хоть чего-то стоит (впрочем, тоже являясь гарантией не полной, но хотя бы максимально возможной).
У нас же (да и у всех «постсоветских») красный диплом не стоит почти ничего в реальном мире. О том и речь.
Человек либо мыслит вообще — то есть понимает что от него хотят, каков контекст задачи, как он влияет на возможное решение. Либо не мыслит — потому что ленив и делает тупо как проще, влоб.

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

Весьма оригинально…
А можно более подробно раскрыть этот более чем странный тезис?
> Не «из-за лени» – а из-за наличия более разумного и быстрого (!) решения.

Но он не предоставил решение. Его задача была — написать по условию диффур и его решить.

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

Ну так влиять на них он не может. Либо они есть (есть что раскрывать), либо нету.

> Увы, нет…
Звание «специалиста» (тут в кавычках) и реальный специалист – совершенно разные сущности.

А где кто говорил о звании специалиста? Речь шла именно о «реальном специалисте».

> Настоящий специалист должен понимать не «что от него хотят» – а что надо делать.

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

Точнее — соль ситуации в том, что в обоих случаях он все _понял_. Но не сделал. Потому что лентяй.

> А можно более подробно раскрыть этот более чем странный тезис?

Я, вроде, уже раскрывал. Если человек хочет препарировать лягушек, то не надо заставлять его раскрываться в области ненавистного рисования. Возможно, вы сможете как-то построить процесс так, что ему будет не особенно отвратно. В итоге он не особенно хорошо научится рисовать (но научится) и даже примириться с тем, чтобы терпеть ненавистную работу. Но это ли то, что должен делать Учитель?
Его задача была — написать по условию диффур и его решить.

Это задача/решение математика. А мы говорим о задаче/решении программиста. И чаще всего это совсем разные методы решения…
Ну так влиять на них он не может.

Ну может же, блджад! Даже я, будучи не преподавателем, а руководителем всяких отделов – мог раскрывать в людях «скрытые таланты». А уж настоящий преподаватель обязан это уметь просто по определению…
Речь шла именно о «реальном специалисте».

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

Вот именно о нагрузке и речь. )))
Первый человек написал «как учили» – долго и тяжело. Второй написал «как правильно» – быстрее и проще, максимально оптимально.
У кого там что упадёт первым, где тут соль, а? )))
Но это ли то, что должен делать Учитель?

Да. Отдавать всего себя обучению своему предмету. И если даже вдруг на курсе оказался «случайный» слушатель – не задача и даже не право Учителя гнать такого слушателя со своего курса.
Его задача – заинтересовать и научить. Все прочие вопросы решают уже другие инстанции.
> Это задача/решение математика. А мы говорим о задаче/решении программиста.

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

> Ну может же, блджад! Даже я, будучи не преподавателем, а руководителем всяких отделов – мог раскрывать в людях «скрытые таланты».

Ну так раскрывается то, что есть. А влиять никак на наличие нельзя.

> Первый человек написал «как учили» – долго и тяжело. Второй написал «как правильно» – быстрее и проще, максимально оптимально.
У кого там что упадёт первым, где тут соль, а? )))

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

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

Ну вот в примере с диффурами человек не решил задачу вообще.

> Да. Отдавать всего себя обучению своему предмету.

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

Мы говорим о любой задаче вообще. Если есть более простое и быстрое решение – нечего городить там диффуры на ровном месте. К чему искусственно усложнять то, что можно сделать проще и быстрее, и даже с тем же результатом? «Процесс ради процесса»?
Ну так раскрывается то, что есть. А влиять никак на наличие нельзя.

На само наличие – разумеется, никак нельзя. Но вот на «раскрываемость» – не только можно, но и нужно.
Иначе у вашего «преподавателя» (тут именно в кавычках) получается какой-то совершенно пассивный подход к вопросу – максимум требований к студентам и ноль требований к себе самому.
Первый напишет как учили — проанилизирует задачу, увидит, что на реальных данный простой алгоритм будет работать слишком медленно и потратит время на оптимизацию.

Так это именно и есть решение втор