Тег ‘программирование’

Вот подумалось тут

Разбирая непрочитанные закладки в браузере, наткнулся на “заложенную” статью о Progressive Web Applications. Я некоторое время назад задумался о простеньком веб-приложении, умеющем работать в “оффлайне” – точнее, способном сохранить введенные в форму данные и затем синхронизировать их с сервером, так что краем глаза увидев “рекламу” концепции Progressive Web Application, подумал – это как раз то, что нужно! Вот сегодня наконец-то руки дошли до погуглить, что это такое и как они делаются – и если честно, я немного офигел.

Идея, если подумать – очень простая. Немалая часть “приложений” для Android или iOS – это несложные обертки над каким-нибудь API, работающим поверх обычного HTTP. Некоторые вообще не парятся и отрисовывают весь пользовательский интерфейс в WebView или как он там называется, и даже реализуют “содержательную” часть приложения на браузерном JavaScript. Так вот, зачем плодить такого рода “приложения”, если можно сохранить на устройстве “главную страницу” сайта (или “приложения”) вместе с необходимым JavaScript и прочими ресурсами (CSS, картинки и так далее)? PWA – это небольшой набор средств, позволяющих добавить специально оформленную веб-страничку в список “приложений” на устройстве с Android или iOS. К этому добавляется возможность зарегистрировать в системе некоторый код на JavaScript для фонового выполнения – эта штука называется ServiceWorker – и готово!

Примерно тот же набор фактов вперемешку с основными принципами разработки “прогрессивных веб-приложений” излагается обычно на паре страниц мелким текстом, засоренных “птичьим языком” про “rich mobile experience”, “new level of quality” и тому подобную ерунду. В худшем случае все сводится к этой самой ерунде, а технические детали опускаются совсем.

Вот мне интересно – в других, отличных от веба разделах того, что обычно называют “информационными технологиями”, отношение количества вот такого буллшита к техническим деталям обычно немного ниже. А почему?

Мнение нормального человека об этой вашей ардуине

Хочу заметить – пишет не “электронщик” ни разу:

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

https://felixit.blog/2018/10/02/pro-arduino/

О профессиональной этике

Полистал тут книжечку Modern Assembly Language Programming with the ARM Processor by Larry D. Pyeatt, в частности, главу про арифметику с фиксированной запятой. В этой главе упоминается про известный случай с заглючившей системой Patriot, а в одном из упражнений предлагается обсудить это, исходя из положений Software Engineering Code of Ethics And Professional Practice.

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

Code of Conduct здорового человека

Крайне рекомендую к внедрению в опенсорсных проектах:

https://github.com/unwireddevices/RIOT/blob/loralan-public-2018.07/CODE_OF_CONDUCT.md

UPD Не все понимают, чем он так хорош – смотрите в сравнении с “Code of Conduct курильщика”.

Еще кого-нибудь обосру – на очереди TU Darmstadt

Вот я, например, ругаю отечественных доцентов, пытающихся преподавать “информатику” и одновременно хвалю всяких там иностранных Керниганов. Впору заподозрить меня в “низкопоклонстве перед Западом” – но нет, обгадить надо всех ровным слоем. Сегодня под раздачу попадет Технический университет Дармштадта – так получилось, что я добрался до тамошних лекций по Allgemeine Informatik (на русский переводится примерно как “общая информатика”), почитал конспект гуглотранслейтом и ужаснулся.

http://www.ke.tu-darmstadt.de/lehre/archiv/ws0607/ai1/material/

Технический университет Дармштадта – это вам не кот чихнул, а, как подсказывает нам Педивикия, “один из наиболее известных технических университетов, является членом TU 9″. Вводный курс по “общей информатике” читает профессор Йоханн Фурнкранц – может, он действительно большой специалист по “искусственному интеллекту”, но преподавать не умеет от слова совсем.

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

Вопрос первый стоимостью 10 баллов – про память компьютера Commodore C64. Мгновенно отсекает студентов, не слышавших слова типа “шина адреса” и “шина данных” – ну или привыкших думать над вопросом, а не мгновенно переводить все встреченные числа в двоичный вид. Теоретически, ответ на этот вопрос можно найти в лекциях – на 6 слайде лекции про фон-Неймановскую архитектуру немножечко рассказывается о разрядности данных и адреса, но многие ли студенты будут в состоянии это запомнить, понять и применить на экзамене?

Второе задание на 12 баллов проверяет склонность к зубрежке и начетничеству, которую многие преподаватели путают с освоением предмета. Вопрос – “что такое дигитализация и почему это важно для современных компьютеров?” Прилежный студент-отличник должен встать по стойке “смирно” и бодро оттарабанить заученное: “Современные компьютеры – это цифровые компьютеры и вся информация, как то: символы, тексты, изображения, музыка, видео и так далее должна быть преобразована в цифровую форму, то есть представлена последовательностью из нулей и единиц!” Просто прекрасен вопрос о том, является ли Java интерпретируемым или компилируемым языком. Интересно, можно ли на экзамене сказать про JIT-компиляцию, или профессор выпадет в осадок?

Задание третье, 8 баллов – таблицы истинности. Ну тут сложно придумать что-то совсем нехорошее. Единственная претензия с моей стороны – вот такие обозначения для всяких там дизъюнкций и конъюнкций только запутывают. Одна и та же операция может обозначаться аж тремя способами (”как в математике”, буковками – OR, AND, NOT, и “как в Java” – &&, ||, !) – не многовато ли?

Задание четвертое аж на 15 баллов. Тут начинается “программирование”. О том, как оно изучается – надо сказать отдельно. Быть может, и неплохо вводный курс программирования начинать с “робота” типа того, который был в учебнике Кушниренко (вообще, “гонять робота по клетчатой доске” – прекрасный способ продемонстрировать “содержательное” программирование, не прибегая к математике типа метода Ньютона или даже квадратных уравнений), но “немецкий” Karel J. Robot – это что-то чудовищное.

Во-первых – может быть, многие уже забыли, но Си-подобный синтаксис – это полная дикость для человека, видящего его в первый раз. Хуже может быть только какой-нибудь APL (и то не факт). Немецкий “робот” – это довольно тонкая “обертка” над языком Java, соединенная с редкостно уебищной IDE. Вы удивитесь, но у живого человека возникают проблемы с тем, надо или не надо ставить точку с запятой после for(…) или if(…), где ставить и где не ставить какие скобки (их, напомню, в Си и других языках с похожим синтаксисом аж три сорта), ну и так далее. В любом редакторе кода для “кушниренковского” (в широком смысле – отношу сюда и разработанного в 57 школе “Робота“) эта проблема решалась тем, что все конструкции языка программирования вводились через контекстное меню (что-то типа Code Snippets во “взрослых” IDE) – здесь же не умеющих программировать студентов оставляют наедине с ущербным текстовым редактором (кажется, даже без подсветки синтаксиса). Зато полдесятка слайдов в лекции по работе с Karel J. Robot и задание в одной из контрольных посвящены всевозможным “орфографическим” ошибкам – что как бы намекает на основные сложности.

Впрочем – и это будет второй и главной претензией к содержанию курса – он вовсе не рассчитан на “не умеющих программировать”. Первый же пример кода в этом курсе появляется во второй лекции (слайд 21). Вы уже знаете, что такое переменная, массив, цикл? Тогда вам остается только покивать головой “Ja, Ja” в ответ на объяснения со следующего слайда. Не знаете? Это ваши проблемы. Я почти не шучу – “программирование” начнется в лекциях по Karel J. Robot и новые понятия будет появляться в бешеном темпе. Прекрасно, если вы что-то слышали про условный оператор и циклы в любом языке программирования. Не слышали? У вас есть три слайда, чтобы разобраться.

Заодно – и это, как я слышал, нередко в немецком “программистском” образовании – в этом курсе очень большое внимание уделяется построению безумных иерархий классов. Я видел выпускника немецкого ВУЗа, считавшего, что он умеет программировать на Java – но все это “программирование” сводилось к написанию кучки классов и интерфейсов. Примером тому может служить и эта задачка.

Столько же баллов “стоит” и задание номер 5 – элементарная задача по работе с массивами. Единственная сложность, видимо – “программирование на бумаге”.

Следующие два задания по программированию – снова “робот” (25 баллов) и Java (15 баллов), надо реализовать довольно подробно расписанное “техническое задание”. Казалось бы, в оцененной в 25 баллов задаче надо как-то проявить смекалку и креативность? Но нет, там тупейший кодинг, сопряженный с борьбой против убогости “робота”.

Что же видим по итогам двух семестров (в техническом университете, хочу заметить)? Проверяемый уровень знаний соответствует примерно российскому ЕГЭ по “информатике”, да еще и отягощен бездумным изучением Java. В курсе не разбирается ни одного хоть сколько-то нетривиального алгоритма (видимо, из-за нехватки времени). Да что там говорить, когда в лекции “Что такое методы” примерно половина слайдов уделена вопросу, чем метод класса (то есть с ключевым словом static) отличается от метода объекта!

Теперь – маленькая вишенка на торте. Напомню, что этот курс читается всем специальностям, где предусмотрена “информатика”, в частности – магистрам по специальности “компьютерная лингвистика“. Два семестра из четырех отводится на этот лютый онанизм, предназначенный скорее для будущих “профессиональных программистов на Java” – и лишь в третьем семестра ВНЕЗАПНО в программе появляется Python с NLTK. Хочется спросить – а почему бы не начать с того же питона? Но нет, сначала надо вынести мозг при помощи Java, а затем немногим выжившим – показать их настоящий профессиональный инструмент.

UPD Первая лекция третьего семестра у компьютерных лингвистов начинается со сравнения Java и Python в духе “в Java ужас-ужас и непонятно, а в Python все очень легко и просто”:

java-vs-python

Вопрос о целесообразности изучения Java в течение двух первых семестров остается открытым.

Заодно – начинать с Java, говорят, вредно и для будущих программистов. Во всяком случае, мучения джависта, пытающегося осознать “модель RAM” из первой же главы книжки Кормена я как-то наблюдал лично.

Быдлохабр, часть очередная

https://habr.com/post/423889/

В комментариях перепись говнокодеров.

Да, если у вас тормозит (сюрприз, да?) страничка хабра с тысячей комментов – то содержательную часть публикации оттуда можно прочитать у автора (на английском, правда):

http://tonsky.me/blog/disenchantment/

Онлайн-IDE с чятиком

А может, кто-нибудь подскажет такую штуку? Хочется работающий в онлайне “многопользовательский” (ну или “на двоих” – чтобы была возможность обсуждать маленькие, почти тривиальные примеры кода, используя для этого что-то поудобнее вконтактика) редактор и компилятор Java, соединенный с текстовым чатом, желательно бесплатный. Пока что нашел два с половиной сайта с близкой, но немного не устраивающей меня функциональностью.

Первый – https://codeinterview.io, он же https://www.remoteinterview.io. Платный, но для моих задач вроде как подходит и демо-версия. Довольно большой выбор языков программирования, есть unix shell и видеочат. Текстовый чат отсутствует. Платная версия дорогая – 500-1000 $ в год, или 5 $ за каждое “собеседование”. Мне кажется, что “для двоих” можно завести одно такое “собеседование”, заплатив 5 $ один раз, или же пользоваться бесконечно оформляемым на разные левые email-ы free trial.

Второй – https://codebunk.com, в отличие от предыдущего варианта, для интерпретируемых языков прикручено окошко с REPL, есть текстовый и видеочат. По-моему, демо-режим поддерживает только одного работающего пользователя. Заметно дешевле предыдущего варианта – 9 $ в месяц.

Гугл выдает еще https://coderpad.io/ – опять же, позиционируется, как инструмент для проведения программистских собеседований, есть компилятор и видеочат, стоит от 50 $ в месяц, free trial на 7 дней – но у меня заработало не во всех браузерах.

Что нибудь еще подобное есть?

Чтобы глупость каждого видна была

Вот, например, некий Михаил Плаксин, доцент из пермского филиала ВШЭ кидает понты в фейсбуке:

plaksin

Ну в целом никто его за язык не тянул – так что “уважаемые оппоненты” пошли на сайт ВШЭ в раздел “Преподаватели и сотрудники” и откопали там страничку доцента с его многочисленными работами, частью даже выложенными для скачивания:

https://www.hse.ru/org/persons/4200771#sci

Продираться через всякий ТРИЗ и прочую “ТРИЗформатику” малоинтересно – а вот получить представление, как большие специалисты по преподаванию информатики что-то рассказывают детям, удалось:

https://yadi.sk/i/gWwvY-h3HDKA0Q

Докопаться, конечно, тут можно буквально до всего – от странных представлений автора о точности вычислений до использования в примерах древнего Turbo Pascal – но тут же есть еще один глобальнейший “косяк”. Приведена куча примеров “неточных” вычислений – и никоим образом не объясняется, что же происходит “на самом деле” (и вообще – написать обширный текст о машинной арифметике и ни разу не намекнуть на IEEE 754 – нужен талант). Что вынесет из этой статьи читатель? “Компьютер считает не всегда точно, что с этим делать и кто виноват – неизвестно”. Неужели именно этого и добивался всеми силами автор?

Understanding the Digital World: What You Need to Know about Computers, the Internet, Privacy, and Security

Оказывается, Брайан Керниган (один из авторов языка программирования C и операционной системы Unix) еще не впал в маразм и недавно (в 2017 году) написал книжку с подзаголовком “что нужно знать о компьютерах, Интернете, приватности и безопасности”.

understanding-the-digital-world

Основное содержание книги – что-то вроде конспекта курса лекций по “Введению в Computer Science”, или CS 109 в университете Принстона (кстати, очень полезно посмотреть задания и лабораторные по этой ссылке). Примерно 3/4 книги повторяют более раннюю “D is for Digital: What a well-informed person should know about computers and communications”, но здесь добавлен новый материал по криптографии, безопасности и тому подобным вопросам.

Если вам интересно, что действительно должно быть в нормальном современном учебнике по “Основам информатики и вычислительной техники” – посмотрите эту книгу и упражнения к ней.

Hadoop против Unix shell

Прикольно как – обработка одного и того же набора данных модными современными инструментами (Amazon EMR и mrjob) занимает 26 минут, а простыми средствами Unix shell – 12 секунд.

https://adamdrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html

“Наивное” решение средствами все той же командной строки обрабатывает те же данные за 70 секунд – что уже вполне терпимо.

Очередное унижение программистов

https://felixit.blog/2018/08/16/elita/

Все так.

PS Что делать, если не хочется получить по морде? Don’t call yourself a programmer.

Ненавижу хохлов

Селюковское самомнение в сочетании с ахромными (по меркам нищей, в целом, Украины) доходами тамошних “айтишников” – термоядерная смесь.

Хуже индусов, честное слово.

fossil

А кто-нибудь в здравом уме (за исключением [info]vitus_wagner) пользовался системой контроля версий fossil?

https://www.fossil-scm.org/

Мне очень нравится тамошняя идея объединить в одно “хранилище” код, документацию в викиобразном формате и тикеты – но можно ли это все использовать в реальной жизни?

А. В. Столяров, “Программирование: введение в профессию”

Посмотрел на свежие “краудфандинговые” книги А. В. Столярова:

http://stolyarov.info/books/programming_intro

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

Можно ли с чисто педагогической точки зрения яростно обличать “стандартизаторов” языков C и C++? Возможно, не все, что они делают – правильно, но стоит ли осуждать в учебнике (!) современные стандарты? Сам автор книги давно ушел из большого секса, но те, кто по этой книге учится сейчас – будут профессионально заниматься программированием через 4-5 лет. Местами есть относительно разумные объяснения, какими возможностями из новых стандартов пользоваться не стоит – но в целом “вместе с водой выплеснули и ребенка”, и, скажем, о существовании того же stdint.h вообще не упоминается. Можно ли сейчас считать компетентным программиста на C, не знающего о существовании этого заголовочного файла – вопрос риторический.

В общем, местами книги можно считать хорошими, местами – приемлемыми, а кое-что вообще следовало бы вычеркнуть. Явно не подходит для “введения в профессию” – а вот как элементарный справочник по программированию в Unix-подобной среде использовать можно, если грамотно отделять тараканов автора от фактического материала.

2018 год

…а люди все еще с удивлением обнаруживают, что внутри ардуины стоит атмега, и что эту атмегу можно программировать на ассемблере:

https://movaxbx.ru/2018/06/05/как-программировать-arduino-на-ассемблере/

Чтобы не забыть

Столкнулся с интересным поведением Linux при попытке изобразить TCP-соединение с помощью “сырых” сокетов (raw sockets), точнее, чего-то на них похожего. Как только на не открытый “явно” (с помощью bind() и listen()) TCP-порт прилетал какой-либо пакет, что-то в составе операционной системы кидало в ответ пакет с флагом RST. Лечится такое поведение двумя способами – можно либо “недосоздать” сокет (вызвать bind(), listen() и не вызывать accept()), либо добавить правило в iptables, не позволяющее отправлять пакеты с RST – что-нибудь в таком роде:

iptables -I OUTPUT -p tcp --tcp-flags RST RST -j DROP

Про беспилотные автомобили

[info]vitus_wagner подкинул ссылку на MIT-овскую статью по модной теме беспилотных автомобилей. Анонс – “В MIT разработали систему, которая позволяет беспилотным автомобилям ездить по сельским дорогам без точной карты” – не очень точно отражает суть работы. Системы типа nVidia DAVE2, довольно простые в реализации (у меня есть даже подборочка материалов по теме) точно так же могут вертеть рулем в нужном направлении, и для своей работы требуют только видеокамеру, смотрящую вперед – данные от GPS и карта там необязательны.

Что отличает эту систему от “нейросетевого” подхода – даже не детерминированность, пусть даже она и приятна (есть несколько публикаций, показывающих, что нейросеть по образцу сделанной в nVidia “сходит с ума” при некоторых манипуляциях с картинкой – вплоть до того, что пытается повернуть совсем в другую сторону, если изменить в картинке на входе всего один пиксель). Внимательно попробуйте осознать описание DAVE2 – эта система определяет угол поворота руля, исходя из картинки, которую видит перед собой “водитель”. Но… Посмотрите на эту схему, в том или ином виде присутствующую в любом вводном материале про спортивное или “экстремальное” вождение:

apeks

Три траектории, изображенные здесь – это три разных способа прохождения одного и того же поворота, в той или иной степени “хорошие” (в зависимости, конечно, от прочих факторов). Для наглядности изображена “шпилька” – поворот на 180°, но вся та же теория остается верной и в том случае, если угол будет другим. “Осознанное” управление автомобилем предполагает, что водитель, подъезжая к повороту (из левого нижнего угла картинки), определит точку поворота руля и точку апекса – и, соответственно, траекторию в повороте. Но обратите внимание, что видимая картинка при приближении к повороту во всех трех случаях одинакова – так что система, полагающаяся в своем принятии решений только на текущий видеокадр, очевидно будет неспособна “выбирать” траекторию. Обратите внимание на то, как в ролике nVidia нейросеть “крутит” руль, дергая его туда-сюда (примерно на 7:32):

А представьте, если это будет происходить не на сухой дороге и не на смешной скорости, а в гололед? На небольшой скорости, имея отличный “запас” сцепления шин с дорогой, можно позволить себе игнорировать “физику” движения автомобиля – что и делают сейчас последователи nVidia. Если же дорожные условия становятся чуть более сложными – то так можно оказаться и в кювете.

Так вот, важнейшее, на мой взгляд, новшество в подходе MIT – это определение траектории, исходя из конфигурации дороги. Границы дорожного полотна их система определяет с помощью лидара, сканирующего пространство вокруг автомобиля с частотой 5 раз в секунду. Затем строится “локальная” траектория (довольно примитивным, правда, образом – ровно посередине между левой и правой обочинами “вписывается” сплайн, то есть достаточно гладкая кривая), и до очередного обновления автомобиль движется по этой траектории. Никто, в общем, не мешает “вписывать” траекторию и более “правильным” образом – скажем, между правой обочиной и серединой дороги, как предписывают ПДД.

Заметьте, насколько это отличается от подхода “авось нейросеть научится” :)

База данных за один вечер и три бутылки пива

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

CREATE TABLE measurements (
    measurementID int NOT NULL AUTO_INCREMENT,
    sensorID int NOT NULL,
    time datetime NOT NULL,
    value double NOT NULL,
    PRIMARY KEY (measurementID)
)

Это очевидно неправильно – имел удовольствие несколько лет подряд наблюдать за эволюцией небольшой SCADA-системы, где хранение данных организовали примерно так. Пока датчиков было немного – оно работало, но примерно на сотне-другой обновляющихся примерно раз в 5-10 секунд датчиков потребовало для работы некоторых костылей. Для начала – в БД перестали записывать “небольшие” изменения данных – скажем, меньше 5% (величина была выбрана довольно произвольно – не надо спрашивать, соответствует ли такой подход требованиям технического задания :) ) от предыдущего сохраненного значения. Затем – по мере накопления данных соорудили чудовищную систему из триггеров и хранимых процедур, которая автоматически создавала “архивные” таблицы сравнительно небольшого размера. Впоследствии, конечно же, выяснилось, что эта система временами глючит и иногда новую таблицу для архива надо создавать вручную.

Наконец, на одном из объектов в дополнение к привычным “медленным” газоанализаторам поставили два десятка акселерометров – и тут все повалилось уже серьезно. Во-первых… нет, для начала в нулевых. Не надо говорить мне, что datetime в SQL неспособен хранить данные с “разрешением” меньше секунды, а опрашиваемый раз в секунду акселерометр бесполезен – тут речь шла уже о том, чтобы записать в базу хоть что-то. А теперь во-первых – показания акселерометров меняются сравнительно быстро и под фильтр “небольших” изменений данных не подпадают, и во-вторых – отказы БД стали чуть ли не ежесуточными. Считайте сами – в сутках 86400 секунд, и при двух десятках пишущих что-то датчиков мы влегкую получаем 1,7 миллиона записей в сутки. Да, часть из них отфильтруется – но и миллиона строк хватит, чтобы популярные СУБД с SQL хорошо и надежно “легли”.

Признаться, я списывал многое из этих проблем на невысокую квалификацию разработчиков этой системы, но после доклада Сергея Аксенова “Антипаттерны разработки программных комплексов для интернета вещей” на Inothings++ понял, насколько героические люди используют SQL для хранения такого рода данных. Про выбор СУБД в видео – с 4:28:

Идея понятна – реляционные СУБД расчитаны на количество строк порядка миллионов (десятков миллионов – если у вас поблизости есть грамотный администратор баз данных), а как легко посчитать – это всего лишь суточный архив сравнительно небольшой системы. Впрочем, случай “Стрижа” еще более-менее прост – частота опроса каких-нибудь ЖКХшных счетчиков относительно небольшая, всего несколько раз в сутки. А что делать, если хочется хранить, скажем, данные по 16 каналам АЦП с небольшой в общем-то частотой дискретизации в 16 тысяч выборок в секунду? Нет, я прекрасно представляю, как это сделать “на файлах”, и это совсем не сложно – простенький формат хранения данных можно полностью реализовать за неделю неспешной работы (собственно, что-то наподобие edflib, но работающее на микроконтролере с сотней килобайт памяти я написал в прошлом году где-то за несколько дней):

Implementing EDF takes a week. EDF+ takes a few weeks but is better and more powerfull. If you still decide to start with EDF, it is wise to adopt the 12 simple additional EDF+ specs.

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

Еще из полезного чтения – статья Luca Deri о системе, названной им tsdb – построенной поверх Berkeley DB системе, обеспечивающей хранение миллионов (!) временнЫх рядов (time series – собственно, это общее название для такого рода данных). Решение не совсем подходящее для моего случая – но опять же содержащее несколько полезных идей.

Для начала – система, многократно превосходящая по производительности решения на основе SQL, реализована всего лишь в 1000 или около того строк кода на Си. Именно это и вдохновило меня на написание собственного решения – 1000 строк это совсем немного, а следовательно, должно быть довольно просто. Второе – данные желательно каким-либо образом объединять – если в tsdb это сделано довольно произвольным образом (в базе много редко обновляемых временных рядов), то в моем случае я просто решил писать “секундные” (или соответствующие какой-то доле секунды) записи, как в EDF.

В общем, осознав эти “три источника и три составные части”, я взял пивка и засел за Visual Studio – и примерно за вечер написал прототип базы данных, оптимизированной под мои требования – десятки-сотни одновременно записываемых временных рядов с частотой дискретизации от единиц до тысяч Гц. Собственно, по факту получился тот же EDF, только записанный в Berkeley DB. Выбор довольно произвольный (прежде всего – ее используют в tsdb) – но эта, так сказать, “встраиваемая СУБД” поразила меня своей простотой. Немного не радует лицензия – хотя при желании могу выложить код на какой-нибудь гитхаб для очистки совести.

Что могу сказать? Не прилагая никаких усилий в части оптимизации, на собственном ноутбуке я “из коробки” получил скорость записи в базу данных около 40-50 Мбит/с (похоже, упираясь в производительность жесткого диска) – причем, судя по всему, падения производительности с ростом числа записей в БД не происходит. Например, в БД размером около 11,5 Гб – это чуть меньше 1,5 миллионов записей по 8 килобайт (в каждой из записей – по 4000 “точек”, каждая из которых – двухбайтовое целое) никакого снижения скорости записи или чтения я не наблюдал (дальше просто стало жалко жесткий диск). Что забавно – тесты “на чтение” демонстрируют полезность кеширования – сначала 10 000 записей читаются за долгие 8 секунд, а затем, если повторить тот же тест “не отходя от кассы” – за 0,22 секунды. Не видел бы – не поверил.

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

PS А если вам все же нравится SQL – почитайте, как правильно организовывать хранение time series в реляционной БД:

https://blog.timescale.com/time-series-data-why-and-how-to-use-a-relational-database-instead-of-nosql-d0cd6975e87c

И все-таки хочу напомнить, что решение “на коленке” практически не уступает приведенному в статье по ссылке в плане производительности (и да, надо бы проверить его с четырехгигабайтным кешем :) ).

Операционная система из говна и палок

На “Гиктаймсе” опубликовали конспект первой лекции курса Олега Артамонова по программированию микроконтролеров. Курс, конечно, немного экзотический в сравнении с любым интернетовским руководством по тем же STM32 – в нем рассматривается программирование с использованием операционной системы RIOT. Никакого вам CubeMX, никакой FreeRTOS – но в целом материал не особо привязан к конкретной ОС и “железу” и ориентирован скорее на то, чтобы продемонстрировать подходы к программированию для микроконтролеров “вообще”.

Для тех, кому проще воспринимать видео – на Youtube выкладываются и видеозаписи лекций:

https://www.youtube.com/playlist?list=PLJEYfuHbcEIApuZR4L5tRiBCwTZCYeTNY

Но при всех заявленных и видимых достоинствах этих лекций, хвалить их целиком пока рано – поэтому перейду к всякой ерунде. Как водится, половина удовольствия от чтения “околоэлектронных” материалов на “Хабре” и “Гиктаймсе” – это комментарии, где обычно ссаными тряпками гоняют ардуинщиков. В этот раз к “гонимым” добавились также те, кто не осилил ничего, кроме всевозможных HAL и StdPeriphLib от производителя, и те, кто почему-то считает микроконтролером Raspberry Pi. Но все это не заслуживало бы упоминания – если бы не один комментарий:

…например, в Contiki — там многозадачность с инвалидностью третьей группы, там надо в треде либо без switch-case, либо без сообщений жить. Этому в университете всех учить не надо, кому в жизни не посчастливится — сами научатся.

https://geektimes.ru/company/samsung/blog/299187/#comment_10699171

Полез смотреть, что же за альтернативный подход к многозадачности исповедуют авторы операционной системы Contiki – и обнаружил там совершенно замечательную штуку. Оказывается, тамошнее подобие “потоков” обычной RTOS реализовано довольно необычно, исключительно средствами языка C.

Для начала – вот такой хитрый пример кода, который обычно называется Duff’s device – “Прием Даффа”, в честь Тома Даффа, обратившего внимание на то, что метки в конструкции switch языка C позволяют нарушать “блочную” структуру программы – например, перейти сразу внутрь цикла:

switch (count % 8) {
    case 0:    do { *to = *from++;
    case 7:         *to = *from++;
    case 6:         *to = *from++;
    case 5:         *to = *from++;
    case 4:         *to = *from++;
    case 3:         *to = *from++;
    case 2:         *to = *from++;
    case 1:         *to = *from++;
               } while ((count -= 8) > 0);
}

Кстати говоря, Duff’s Device упомянут [info]sharpc в известном “Теоретическом минимуме для программиста“. Конструкция довольно дикая, мало чем отличающаяся от GOTO – и хочу заметить, что особых преимуществ по скорости (в оригинале она использовалась для того, чтобы развернуть цикл в memcpy) на современных процессорах она не дает. Знать о ней, наверное, надо, а вот применять – только по необходимости.

А теперь сделаем еще один шаг вперед – обратите внимание, что такой переход позволяет “сохранить” текущее положение “внутри” выполняемой функции. Сначала пример без макросов (взятый со странички Адама Дункельса про protothreads и немного измененный):

volatile int counter;

int example( int *lc ) {
    switch ( *lc ) { case 0:

    printf( "First run!\n" );
    while ( 1 ) {
        *lc = 9; case 9: if ( !(counter > 10) ) return 0;
        printf( "Threshold reached\n" );
        counter = 0;
    }

    } *lc = 0; return 2;
}

Будем вызывать эту функцию примерно таким образом:

int main( void ) {
    int lc = 0;

    while ( 1 ) {
        example( &lc );
        printf( "Back in main, counter = %d\n", counter );
        counter++;
    }

    return 0;
}

Обратите внимание, что строчка First run! напечатается только один раз, несмотря на то, что функция вызывается многократно. Фактически, таким нехитрым приемом реализован механизм ожидания событий – нетрудно догадаться, что в промежутках между вызовами нашей функции counter может изменяться как угодно (на это я намекаю, объявив его volatile). А теперь определим несколько макросов:

struct pt {
    int lc;
};
#define PT_BEGIN(pt)          switch((pt)->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c)  pt->lc = __LINE__; case __LINE__: if(!(c)) return 0
#define PT_END(pt)            } (pt)->lc = 0; return 2
#define PT_INIT(pt)           (pt)->lc = 0

И перепишем пример, используя их:

volatile int counter;

int example( struct pt *pt ) {
    PT_BEGIN( pt );

    printf( "First run!\n" );
    while ( 1 ) {
        PT_WAIT_UNTIL( pt, counter > 10 );
        printf( "Threshold reached\n" );
        counter = 0;
    }

    PT_END( pt );
}

int main( void ) {
    struct pt example_pt;
    PT_INIT( &example_pt );

    while ( 1 ) {
        example( &example_pt );
        printf( "Back in main, counter = %d\n", counter );
        counter++;
    }

    return 0;
}

Хочу добавить, что в компиляторе из Microsoft Visual Studio этот пример не работает, если при компиляции указан параметр /ZI (он по умолчанию установлен для конфигурации Debug) – можно заменить его на /Zi.

Оцените, что получилось – исключительно средствами языка C реализован простенький, из говна и палок, механизм кооперативной многозадачности. Если добавить к нему планировщик и, скажем, какой-нибудь таймер, то получится та самая операционная система Contiki – названная в честь построенной из тех же говна и палок лодки Тура Хейердала. Теоретически, в Contiki есть и механизм вытесняющей многозадачности – но реализован он не для всех архитектур, в отличие от кооперативной, для которой достаточно лишь компилятора C. Это позволяет “портировать” ядро Contiki куда угодно.

Какие же у этого подхода недостатки? Начну с очевидного – использовать одновременно и protothreads, и конструкцию switch нельзя. Другая нехорошая штука – при переходе потока в состояние ожидания и выходе в планировщик теряются значения всех локальных переменных внутри функции этого потока. Это довольно неприятно, так как требует постоянно держать в голове “нестандартное” поведение программы. Бороться с этим можно либо объявляя локальные переменные потока, как static, либо используя глобальные переменные. Наконец, ждать событий можно только в основной функции потока, что резко ограничивает “полет фантазии” в реализации какой-то нетривиальной логики.

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

Глазами ученого на Хабре

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

https://habrahabr.ru/post/349624/

В комментах, правда, выясняется, что “ученый” тоже в говне моченый, но и “оппоненты” отжигают не по-детски.

PS И даже не знаю, какой из этих двух вариантов омерзительнее:

C и С++ изучают только программисты. Естественнонаучники (за очень редким исключением) учат программирование на Делфи, а потом всякие спецпакеты. Максимум пролог будет. Там не учат С98. Там не учат что памятью в принципе можно управлять. Тем более — что нужно. Учат так: вы придумываете правильный алгоритм, компьютер его выполняет. Учат как переписать алгоритм из головы на паскаль.

https://habrahabr.ru/post/349624/#comment_10682588

или

Я не знаю где вас учили, но на моём естественно-научном факультете сначала был курс C# (2 года). А теперь вообще идёт курс Java EE c Хадупами и всем фаршем.

https://habrahabr.ru/post/349624/#comment_10682700