Большой айтишный пузырь

Вот почитал тут про фронтендера, который за 280 тысяч в месяц рефлексировал со Светой и Леной на диване — а там рядышком есть аналогичная статья про программиста-эмбеддера из Иваново, который за впятеро меньшие деньги вынужден обходиться без Светы, и даже с диваном некоторая напряженка:

https://journal.tinkoff.ru/electronic-engineer/

Так вот, у наивных людей иногда возникает вопрос — откуда и почему такая несправедливость, почему долбоеб-фронтендер рефлексирует на диване со Светой и получает за это 300кк/сек, а эмбеддер, которому и знать надо больше, и ответственность выше на порядок, перебивается с хлеба на воду? Ответ прост и понятен — если попытаться разобраться, «откуда берутся деньги».

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

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

Говоря проще — не связанное с производством чего-то материального «айти» всеми способами стремится «набить себе цену» — и пока что это у программистов неплохо получается, надо сказать. Хотя первые звоночки, вроде нашумевшей статьи про LinguaLeo, уже пошли!

PS «Надеюсь, вы уже поняли, какую ошибку совершили, выбрав программирование микроконтроллеров в качестве своей основной специальности»

Однажды я смотрел фильм, который начинался так же

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

https://journal.tinkoff.ru/diary-frontender-moscow/

Дальше тема Светы, Лены и дивана не раскрыта. Одно слово — фронтендер:

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

Бесит, сука

Очередные талантливые программисты не осилили пересчет из int16 во что-то более им подходящее. В следующий раз сделаю вывод данных в формате binary coded decimal, а то достали.

Хотя нет — напишут что-то вроде Float(x.toString(16)) и будут считать себя неибаццо гениями. Подскажите, в каком формате выводить числа, чтобы на той стороне с гарантией охуели?

Программисты не нужны

Наблюдал сегодня подгорание жепп всевозможных «бекендеров», прочитавших вот эту статеечку на хабре:

https://habr.com/ru/company/lingualeo/blog/515530/

Краткий пересказ: в LinguaLeo взяли Chief Technical Officer-ом некоего чувака, хорошо знавшего PostgreSQL — даже слишком хорошо, настолько, что он переписал на хранимые процедуры существенную часть бекенда. Результаты, например, по одной из задач говорят сами за себя:

Было Стало
Строк кода 10 000 300
Запросов к БД 12 1
Время выполнения, мс 600 20

Попутно были выставлены на мороз все веб-макаки, поддерживавшие то поделие:

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

Читатели почуяли, что их ценный навык переписывания JSON-ов на PHP стремительно теряет ценность и начали кидаться на автора, мол, ни черта он не понимает в разработке уеб-приложений. Обязательно зайдите в комменты, там феерично.

Язык Си образца 70-х годов

Есть одна статейка, описывающая портирование Unix с PDP-11 на VAX (кстати, вопреки обычно озвучиваемому мнению о легкой переносимости Unix между разными архитектурами, именно продукция фирмы Digital долгое время была основной и практически единственной «платформой» для Unix):

https://www.bell-labs.com/usr/dmr/www/otherports/32v.pdf

На последней страничке приведены пожелания для доработки компилятора, очень интересны пункты 2 и 3:

Based on our experience, we strongly recommend that the C language and its compilers be enhanced so that:
<…>
2. The ’->’ operator is checked to insure that the structure element on the right is a member of a structure to which the pointer on the left may point.
3. A structure element may be declared with any name as long as the name is unique within the immediately surrounding structure. (The current requirement that a structure element name must uniquely correspond to an offset from the beginning of the structure, across all structures in a compilation, creates naming problems and frequently leads to errors of the type noted in item 2 above.)

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

struct A {
    int first;
    int second;
};

struct B {
    int first; /* Так нельзя - имена членов структур должны быть уникальны, first уже есть в struct A, см. пункт 3 */
    int second;
};

struct C {
    char c_first;
    int c_second;
};

struct C c;
c.second = 123; /* Компилятор съест и не подавится, но запишет это 123 совсем не туда, куда хотелось бы, см. пункт 2 */
/* То же самое с точки зрения современного Си: */
((struct *A) &c)->second = 123; /* Ты сам себе злобный Буратино */

При этом это поведение, странное с точки зрения «высокоуровневого» программиста и абсолютно нормальное — с точки зрения «низкоуровневой», когда мы думаем о байтиках в памяти, использовалось в коде Unix сплошь и рядом, как подсказывает нам статья, и явно привело к немалому количеству сюрпризов при переходе с 16 бит на 32.

Кстати, посмотрел на выходных на Django

В очередной раз возникла идея одного веб-приложения — ну и на выходных нашел часочек для прохождения Django tutorial. Выводов для себя сделал три:

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

Про Python, программистов и математиков…

…или зачем математикам программирование, или программистам — математика.

Посмотрел краем глаза на один прожект, где слепили обработку загружаемых пользователем аудиофайлов на Python, разумеется, с использованием SciPy (на это ума хватило). «Обработка» — громко сказано, на самом деле все сводится к обычной линейной алгебре. Беда в том, что файлы немаленькие — скажем, два канала с частотой дискретизации 44,1 кГц и разрядностью в 16 бит. Часовая запись — это уже 600 Мб, которые для использования SciPy надо полностью загрузить в память. Заодно там надо как-то хранить и промежуточные результаты вычислений — и в результате объем сожранной питоном памяти растет просто катастрофически.

Впрочем, память сейчас кажется дешевой, а подход «закидать проблему железом» — работающим. Так вот, при желании почти всю «обработку», которая есть в этом проекте, можно было бы сделать практически «в режиме онлайн», со скоростью загрузки или чтения файла с данными, а заодно — с в разы меньшим потреблением памяти. Нечто подобное я как-то делал даже для микроконтроллеров класса «за 2$ на алиэкспресс», с каким-нибудь ядром наподобие Cortex-M3, а лучше M4, и десятком-другим килобайт ОЗУ.

Беда в том, что условные «математики», сделавшие первую демонстрацию алгоритмов на SciPy (это модно и «научно»), не хотят лезть в программирование, а программисты не понимают примерно ничего из написанного на SciPy (ну например, хотя бы того, что делает функция numpy.dot).

С другой стороны, конечно, никакая оптимизация тому проекту не поможет — при 1 пользователе эта демонстрашка работает, при 10 придется докинуть памяти, при 100 пользователях может возникнуть проблема — компьютеры с потребным количеством памяти делает разве что IBM; другое дело, что 100 пользователей у того проекта никогда не будет.

Бесит, сука

Вот посмотрел я на то, из чего состоит rawStoreBallotTx, передающийся на сервер и сохраняющийся в блокчейн при электронном голосовании в Москве. Разбираться с обширным кодом клиента Exonum на Javascript я не стал, а просто глянул на сами данные.

58 1c c8 b3 ed 95 97 f3 f4 ab c7 76 1d 17 c3 02
a3 d5 3e 59 c8 c7 6c 55 04 4b f0 d3 91 e7 fc c1
00 00 e9 03 06 00 0a 40 64 61 38 35 66 61 66 38
34 66 61 65 62 30 65 39 30 65 66 33 31 61 32 65
37 32 35 32 34 31 35 31 66 62 61 63 30 65 32 66
36 65 36 63 34 39 38 33 36 30 31 33 64 36 34 35
32 39 34 36 39 38 38 64 10 4d 1a 56 0a 14 bc ef
fd 5e 5e a6 8a 6b b2 d9 04 31 dd 51 2e 11 5e 4c
44 e3 12 1a 0a 18 9b 37 cb a5 f0 26 25 ca 74 45
00 21 88 e1 59 ca 56 ee d5 24 dd 25 d3 26 1a 22
0a 20 57 1d b7 6c 24 f5 85 22 7e 75 4c ca e6 97
99 8f f6 22 6b 24 58 94 b9 0d 57 b0 f3 d5 9a 0c
16 01 9d c1 e2 eb 1d 8d 8a cf 12 60 27 3f f0 2e
cc ba 5d 9f 61 e0 ba 51 a7 d2 26 78 82 d1 05 6d
a5 92 93 75 7d 5a c5 23 e0 45 f7 f9 8d 6b ed 4f
33 fe d7 c2 e2 48 77 c6 61 9b 10 86 b3 c7 a7 73 
3f 0d

Первые 32 байта — это некий идентификатор под названием accountAddressBlock; дальше начинается что-то непонятное — но резко выделяется довольно длинная последовательность из байт в диапазоне 30—39 и 60—66 — это цифры и буквы от a до f. Выпишем ее отдельно (справа — символы, которым эти байты соответствуют):

                        64 61 38 35 66 61 66 38            da85faf8
34 66 61 65 62 30 65 39 30 65 66 33 31 61 32 65    4faeb0e90ef31a2e
37 32 35 32 34 31 35 31 66 62 61 63 30 65 32 66    72524151fbac0e2f
36 65 36 63 34 39 38 33 36 30 31 33 64 36 34 35    6e6c49836013d645
32 39 34 36 39 38 38 64                            2946988d

Что это? А это как раз voting id, идентификатор голосования — только зачем-то переданный в виде текста. Сразу же хочется обратить внимание на байт 40, стоящий непосредственно перед voting id — да и вообще на всю последовательность 00 00 e9 03 06 00 0a 40 — хочется считать ее неким заголовком, а 40 — длиной поля. По аналогии находим еще три подобных последовательности — «заголовок» 10 4d 1a 56 0a 14 (в кавычках, и я сейчас объясню, почему) предшествует 20 байтам

                                          bc ef
fd 5e 5e a6 8a 6b b2 d9 04 31 dd 51 2e 11 5e 4c
44 e3

Заголовок 12 1a 0a 18 — последовательности из 24 байт:

                  9b 37 cb a5 f0 26 25 ca 74 45
00 21 88 e1 59 ca 56 ee d5 24 dd 25 d3 26

А заголовок 1a 22 0a 20 — 32 байтам:

      57 1d b7 6c 24 f5 85 22 7e 75 4c ca e6 97
99 8f f6 22 6b 24 58 94 b9 0d 57 b0 f3 d5 9a 0c
16 01

Казалось бы, это вся информация для записи в блокчейн? Но нет — не хватает district id, номера «участка» (здесь он принимал логичные значения 77 и 52 для Москвы и Нижнего Новгорода соответственно). Где он мог потеряться? Оказывается, первый «заголовок» из 6 байт — это на самом деле еще и поле с номером участка, 10 4d (4d в шестнадцатиричной системе — это как раз 77).

В оставшихся 64 байтах я какой-то структуры уже не увидел, но в целом для расшифровки голоса они нам уже не нужны. Вспоминаем структуру данных для передачи — это должны быть зашифрованный голос, nonce и публичный ключ пользователя; в используемой для голосования библиотеке NaCl длина nonce и публичного ключа как раз составляет 24 и 32 байта соответственно, 20 байт — это длина сообщения. Кажется, мы нашли все необходимое? Проверяем несложной программой:

unsigned char message[] = {
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0xbc, 0xef, 0xfd, 0x5e, 0x5e, 0xa6, 0x8a, 0x6b,
    0xb2, 0xd9, 0x04, 0x31, 0xdd, 0x51, 0x2e, 0x11,
    0x5e, 0x4c, 0x44, 0xe3
}; // first 16 bytes must be 0

unsigned char nonce[] = {
    0x9b, 0x37, 0xcb, 0xa5, 0xf0, 0x26, 0x25, 0xca,
    0x74, 0x45, 0x00, 0x21, 0x88, 0xe1, 0x59, 0xca,
    0x56, 0xee, 0xd5, 0x24, 0xdd, 0x25, 0xd3, 0x26
};

unsigned char public_key[] = {
    0x57, 0x1d, 0xb7, 0x6c, 0x24, 0xf5, 0x85, 0x22,
    0x7e, 0x75, 0x4c, 0xca, 0xe6, 0x97, 0x99, 0x8f,
    0xf6, 0x22, 0x6b, 0x24, 0x58, 0x94, 0xb9, 0x0d,
    0x57, 0xb0, 0xf3, 0xd5, 0x9a, 0x0c, 0x16, 0x01
};

unsigned char dit_private_key[] = {
    0xdb, 0x77, 0xd6, 0x2f, 0xc8, 0x87, 0x26, 0xf1,
    0xc5, 0xa6, 0xb7, 0x9b, 0x00, 0x3b, 0x3b, 0xca,
    0x83, 0x34, 0x9e, 0x33, 0x43, 0x37, 0xde, 0x84,
    0xbd, 0x17, 0x34, 0x4a, 0xb6, 0x01, 0xdb, 0x74
};

unsigned char buf[sizeof(message)] = { 0 };

int res, vote;

res = crypto_box_open(buf, message, sizeof(message), nonce, public_key, dit_private_key);
vote = *((int*)(buf + crypto_secretbox_ZEROBYTES));
printf("%x\r\n", vote);

И действительно — расшифрованное сообщение содержит 4 байта 1a d5 be 0d — голос «против» на этом голосовании.

Так вот, возвращаясь к тому, что бесит. Во-первых, бесят просранные талантливыми фронтендерами 32 байта — зачем засовывать voting id в виде строки? Во-вторых — бесит полное отсутствие описание формата передаваемых данных — вот я его разобрал довольно элементарным способом, но пока так и не знаю о назначении еще 64 байт в конце — похоже, что это как-то связано с блокчейном и криптографической подписью для него, но я не уверен.

Боженька, побей их всех по голове ЕСПД.

Randall Kanna

Пацаны и пацанессы, а что вы можете сказать о вот этой мадам?

https://randallkanna.com

Я пока что увидел на ее сайте только многочисленные советы из серии «Как пройти программистское собеседование» и «Как построить личный бренд» вместе с самолюбованием из серии «как я за полтора года стала senior engineer«.

Второе поколение

Вот еще — хочу сознаться, что зря я гнобил TU D-stadt, и даже там на факультете информатики можно научиться чему-то полезному, если вам повезет, конечно. Дело в том, что вводный курс по информатике, с программированием на Java, читают два разных преподавателя — раньше в четные годы это был Prof. Dr. Johannes Furnkranz (ссылки на его курс можно найти у меня), сейчас курс на основе сделанного Furnkranz’ем читает более молодой преподаватель, Prof. Dr. Christian Reuter. А если повезет, и вы поступите на факультет информатики в нечетный год — то курс с формально тем же содержанием читает Prof. Dr. Karsten Weihe (в отличие от предыдущих, заслуживший страничку в немецкой википедии) — и это совершенно другое дело!

Нет, формально оба преподавателя читают примерно одно и то же — но возьмем тот же пример с определением, является ли строка палиндромом. Самостоятельная ценность у этой задачи близка к нулю — но она прекрасно демонстрирует, как писать нетривиальные циклы и обращаться к элементам массива по индексу (да еще и с возможностью «попасть» на off-by-one error). В лекциях и домашних заданиях курса господина Weihe прослеживается какое-то понимание того, зачем нужны все эти задания, и что за ними стоит на самом деле; если же посмотреть на «альтернативный» курс — то иногда возникает впечатление, что автор заданий, типа того же палиндрома, держал перед глазами список «типовых задач», да так и не понял его.

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

А ведь если подумать — то связные списки — это «естественный» для Lisp-подобных языков способ организации данных, да и аппаратная их поддержка — не так уж и сложна (примером чему служат всевозможные «Lisp-машины»). Ничто не мешает рассматривать их, как вполне равноправные с массивами (которые имитируют обычную память с линейной адресацией) «элементарные» структуры данных — и строить на их основе что-то более сложное. Но многие ли в «нашем поколении», полностью захваченном обычными фон-неймановскими компьютерами, могут себе представить «альтернативные» варианты? Многие ли могут понять теоретическую важность других способов организации памяти, чем очевидный «массив из int8_t»? Да и рассуждать о способах построения алгоритмов — скажем, об «индуктивных функциях» или доказательстве правильности рекурсивных функций, имея под рукой такую структуру данных, как список, очень удобно (хотя никто не мешает делать это в «императивном» духе).

И возвращаясь к «смене поколений» — если «старики» еще понимают, чему соответствуют все эти нетривиальные штуки в курсе «информатики», то новое поколение действует «по инерции», понимая свою задачу скорее в «начетническом» ключе — если те же списки или палиндромы встречаются в курсе, то достаточно предъявить некоторое количество задач, где как-то фигурируют эти понятия (при этом совершенно теряя суть происходящего). Худший же вариант — рассказать о списках на примере встроенного в Java интерфейса List — встречается, на мой взгляд, пугающе часто.

PS Интересно, а бывают ли учебные курсы Java, где в качестве примеров разбираются реальные классы из JDK? Тот же java.lang.String — прекрасное наглядное пособие для изучения массивов, например :)

Еще раз про MATLAB

Сим постановляю:

  • Считать MATLAB Coder кривым куском говна;
  • Сайт techbriefs.com приравнять к рекламным листовкам, напечатанным на мягкой бумаге;
  • Его читателей считать говноедами.

А теперь подробнее — несложная функция в два десятка строк на MATLAB (содержащая в основном операции с матрицами — несколько вычислений нормы и умножений) с помощью этого прекрасного инструмента превращается в четыре (!) полуработающих функции на C, общей длиной — что-то около 3000 (!) строк кода. Ни одна из функций не работает полностью правильно, на всех возможных вариантах входных данных. Написанная вручную функция, делающая то же самое — всего 80 строк (в SLOC и того меньше, комментарии мне сейчас считать лень). Как это соотносится с декларируемыми в статейке «benefits»:

no need to schedule time for hand-coding GN&C algorithms (60,000+ SLOC were autocoded by the Critical Design Review), and a detailed requirements review was replaced by a review of MBD artifacts that had proven functionality

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

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

Листал тут твиттер и наткнулся на твит @ID_AA_Carmack, где тот пишет о том, как помогал привести в божеский вид симулятор распространения вирусных заболеваний под авторством Имперского Колледжа Лондона. Симулятор можно найти на гитхабе:

https://github.com/mrc-ide/covid-sim

Есть пара мыслей о полезности программистов во время массовых эпидемий. Во-первых: симулятор написан на банальном и тупом Си. Никаких модных концепций вроде объектно-ориентированного или функционального программирования, никаких этих ваших хаскеллей с монадами и прочей такой хероты. Просто банальный «процедурный» код, местами — в стиле книжки Numerical Recipes или, прости господи, в неподражаемом духе «you can write Fortran in any language«. Тупо — но просто и понятно:

Before the GitHub team started working on the code it was a single 15k line C file that had been worked on for a decade, and some of the functions looked like they were machine translated from Fortran. There are some tropes about academic code that have grains of truth, but it turned out that it fared a lot better going through the gauntlet of code analysis tools I hit it with than a lot of more modern code. There is something to be said for straightforward C code. Bugs were found and fixed, but generally in paths that weren’t enabled or hit. Similarly, the performance scaling using OpenMP was already pretty good, and this was not the place for one of my dramatic system refactorings. Mostly, I was just a code janitor for a few weeks, but I was happy to be able to help a little.

https://mobile.twitter.com/ID_AA_Carmack/status/1254872369556074496

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

Угадали? Правильно — ноль!

Как мне кажется, в скором времени надо будет отлавливать всяких там фронтендеров, бекендеров, сеньоров с трехлетним стажем, дата-саентистов и прочих специалистов по бигдате и строго спрашивать — «А что ты сделал для борьбы с ковидом?» За ответы вроде «высрал сто комментариев на хабре», «напечатал на 3D-принтере клапан для ИВЛ» и тому подобные — выводить в чистое поле к стенке отправлять санитаром в чумной барак.

Про бигдату

Вот искал на днях что-то про бенчмарки всяких там ARM-ов, и наткнулся на пару публикаций, где на наглядном примере демонстрируется, что такое — big data, а что — хуйня из-под коня.

Раз (https://inspirehep.net/literature/1424617):

Projects such as the Large Hadron Collider at CERN generate enormous amounts of raw data which presents a serious computing challenge. After planned upgrades in 2022, the data output from the ATLAS Tile Calorimeter will increase by 200 times to over 40 Tb/s.

Два (http://crm-en.ics.org.ru/uploads/crmissues/crm_2015_3/15728.pdf):

The term ”Big Data” has caught on in the mainstream media and science worlds. While this word in now ubiquitous and almost exhausted in it’s use it still identifies an important issue in the science community. Processing data is getting more difficult due to the shear amount being produced. In the year 2022 the ATLAS detector will be upgraded and in doing so will produce in the order of Petabytes per second of raw data [ATLAS C 2012 Letter of Intent…, 2012]. There is no feasible way to process this much data in a reasonable amount of time. This is largely due to external Input/Output (I/O) bottlenecks present in current super computing systems. A team at the University of the Witwatersrand, Johannesburg is actively involved in the development of a computing system which is both cost-effective and able to provide high data throughputs in the order of Gigabits per second. There are four widely accepted computing paradigms. The first, and most commonly known, is the High Performance Computing paradigm (HPC) which is focused on the raw number of calculations performed per second. The second is the Many Task Computing (MTC) which focusses on the number of jobs that can be completed in a given amount of time. Real Time Computing (RTC) involves very strict restrictions on execution times (such as air-bag sensors or process controls). Finally, a fourth paradigm called Data Stream Computing (DSC) involves the processing of large amounts of data with no off-line storage.

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

Про учебники по C++

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

А если говорить о dark side образования — ознакомился на днях с конспектом курса «С++ для математиков», который в TU D-stadt читают Dr. Alf Gerisch и Dr. Adrien Semin. Курс представляет собой какую-то смесь из странным образом подобранных элементов C++ и взятых из численных методов примеров.

Из положительного хочется отметить разве что довольно подробную лекцию о IEEE 754 с некоторыми примерами правильных вычислений с плавающей запятой (например, с решением «плохих» квадратных уравнений). А вот отрицательного, к сожалению, гораздо больше. Во-первых — разбираемое в лекциях подмножество C++, как бы это сказать… совершенно недостаточно для нормальной продуктивной работы. Это такой поверхностный обзор в стиле введения в «Язык программирования C++» Страуструпа — вот у нас есть классы, вот как выглядит наследование и полиморфизм (множественное наследование не разбирается), вот есть шаблоны (делаем класс Polynom), вот библиотека STL (в ней есть класс vector).

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

int main(void)
{
    // list of two base class pointers
    numInt1D** integrator = new numInt1D*[2];
    // fill with two pointers to derived class objects
    integrator[0] = new numInt1D_rectangleLeft(0.0, 1.0, &f);
    integrator[1] = new numInt1D_trapezoidal(0.0, 1.0, &f);
    // output numerical integral approximations
    std::cout << "Integral approximation using rectangle rule = "
        << integrator[0]->integrate() << std::endl;
    std::cout << "Integral approximation using trapezoidal rule = "
        << integrator[1]->integrate() << std::endl;
    // clean up
    delete integrator[0]; delete integrator[1];
    delete [] integrator;
    return 0;
}

Вообще, не раз наблюдал вот такую ничем не объяснимую любовь к new в C++ у быстро переученных на него джавистов.

Есть, конечно, одно обоснованное возражение - а зачем студентам-математикам учить C++ в каком-то приближенном к реальной жизни объеме, тем более, что для численных методов этого достаточно? Вот возьмем для примера мехмат МГУ - который, в отличие от факультета математики провинциального немецкого ВУЗа, все-таки пытается готовить профессиональных математиков (а пошедшие в программисты выпускники для факультета - третий сорт, после преподавателей этой самой математики). Что входит в "Практикум на ЭВМ" на втором курсе? Отнюдь не только численные методы, но еще и "тонкости" вроде "Десять способов неправильного описания прототипов методов сложения (operator+) и "увеличить на" (operator+=) и единственный правильный способ", да и совершенно "практические" вещи типа библиотеки Qt стороной не обошли. В курсе есть достаточно мест, где можно наступить на стандартные C++-ные грабли и навсегда их запомнить (а нормальное обучение C++ и должно строиться на том, что все эти многочисленные "грабли" надо собрать в процессе обучения самостоятельно и больше их не забывать).

У немецких же товарищей - все наоборот, грабли старательно обходятся, и успешно сдавший экзамен студент знает C++ в том объеме, который позволит ему разве что наделать кучу опасных ошибок.

PS PDFку с лекциями очень просили не распространять, если будут какие-то вопросы - пишите.

Про COBOL, американскую компьютерную выставку и Госуслуги

Вот пишут, что IBM предлагает бесплатные курсы по изучению COBOL — популярного лет 40 назад языка программирования для всяких бухгалтерских, окологосударственных и прочих «учетных» систем:

https://www.inputmag.com/tech/ibm-will-offer-free-cobol-training-to-address-overloaded-unemployment-systems

Якобы учет безработных в американской службе занятости сделан давным-давно, разумеется, на COBOL, и сейчас из-за массового роста обращений туда требуется эту систему поддерживать, как-то развивать и все такое. В «давным-давно» охотно верится — в брошюре с выставки «Информатика в жизни США» — а это 1987-1988 год, вообще-то! — рассказывается про почти современный уровень компьютеризации (ну с поправкой разве на то, что фронтендеров тридцать лет назад еще не придумали).

Но вот гляжу я на всякие отечественные кривые поделия типа тех же Госуслуг или творчества ДИТа г. Москвы и с ужасом думаю — а что будет с этим через три десятка лет, и что будет тогда вместо COBOL?

Боженька, жги, здесь уже ничего не исправить

Чуваки запускают маленькую и простую программу почти без всяких внешних зависимостей (OpenSSL разве что нужен) с помощью docker:

https://fossil-scm.org/forum/forumpost/5f106b752f

При этом (проверено) fossil работает на любой более-менее разумной платформе — от настольного Windows до shared-хостинга с Linux, легко собирается из исходников в практически любом unix-подобном окружении, и зачем при этом паковать его в docker — решительно непонятно.

Опенсорс здорового человека и опенсорс курильщика

Здоровый человек — когда к нему обращается Motorola с просьбой доделать SQlite до пригодного для применения в продакшене состояния, отвечает: «Да, конечно, деньги платить сюда«:

The first release of version 2.0 came out just a couple days after the 9/11 event… But that got to be really popular, and before long I started getting phone calls, and I got a phone call from Motorola. I don’t know if you remember, but back then Motorola was the world’s leading manufacturer of cell phones. And they said, “Hey, we wanna put SQLite on all our cell phones, but we need you to make some enhancements for us. Can we bring you on contract to make these enhancements and to support it?” I said, “Sure, of course.” I hung up the phone and felt “Wow! You mean you can make money off of open source software?” Who knew…?

Курильщик — когда к нему обращается крупный немецкий автопроизводитель с просьбой слегка допилить curl, начинает пороть чушь:

About this time last year a 48-year-old software developer in Sweden named Daniel Stenberg received a panicked call one evening from a large German automaker. The car company, which Stenberg declines to name, asked that he fly to Germany immediately because an application Stenberg had written was causing the entertainment system software in 7 million cars to crash. “I had to inform them that, you know, this is a spare-time project for me and that I have a full-time job and can’t just go to Germany for them,” Stenberg says. “They started out pretty demanding, but then switched when they realized the situation they were in.”

Ебучее красноглазие

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

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

Обожаю, сука, теоретиков

Вот некоторые люди, не будем показывать пальцем, любят строить свою картину мира (в последнем абзаце) по рекламным листовкам типа таких:

https://www.techbriefs.com/component/content/article/tb/techbriefs/aerospace/28025

Так вот, немного оторвавшись от разгребания нагенерированного MATLAB Coder’ом говна, скажу — все эти заявления про торжество «model-based design» на основе MATLAB — чистая реклама, к реальности имеющая очень опосредованное отношение. Для тех, кто не знает — MATLAB — это такой весьма кривой и уебищный язык программирования в комплекте с не менее кривой и уебищной IDE, имеющий, впрочем, ровно два достоинства:

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

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

i100500 = b_mxA->size[0] * b_mxA->size[1];
b_mxA->size[0] = b_mxB->size[0];
b_mxA->size[1] = b_mxB->size[1];
emxEnsureCapacity_creal_T(b_mxA, i100500);

Ругаться закончил.