Опенсорс без понимания

Вот очень показательная заметка на хабре:

https://habr.com/ru/post/681614/

Наглядно показывает уровень деградации буквально одним-единственным предложением:

Сейчас же, когда QMK, наконец, добавили поддержку данного контроллера, в нашем распоряжении 2mb+ встроенной памяти, на которые мы можем «подгрузить» все полезные фишки для повышения продуктивности и удобства.

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

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

Bertsekas, Gallager, Data Networks

Есть на всяких околоайтишных специальностях в вузах предмет под названием «Сети передачи данных» или как-то типа того, где про модель OSI рассказывают, TCP/IP всякое, маршрутизацию и тому подобные вопросы. Есть по нему масса учебников — Олиферы всякие, Таненбаум книжку написал, Куроуз-Росс, Горальски, Стивенс — в общем, на любой вкус, айтишники любят. Содержание в целом более-менее стандартное — вот вам модель OSI, вот вам кучка протоколов с каждого из уровней, вот так работает маршрутизация… — разница в нюансах, где-то больше теории, где-то добавляется практика какая-то. В целом, конечно, это в основном беллетристика и перечисление готовых сетевых протоколов, которые кем-то придуманы — а понимать, почему это все работает — это не вашего айтишного ума дело.

А есть старая (1993 год! а первое издание даже издательство «Мир» в 1989 году перевело) книжка Бертсекаса и Галлагера: http://web.mit.edu/dimitrib/www/datanets.html. Чем она отличается? На первый взгляд, все начинается довольно культурно — модель OSI в первой главе с описанием ее уровней, дальше — немного про всякие протоколы (в основном представляющие собой чисто исторический интерес, из более-менее актуального во второй главе можно назвать только TCP) — но вот в третьей и четвертой главе начинается самое веселье! Внезапно плотность формул на страницу текста становится запредельной, возникает «тяжелая» математика — прежде всего тервер и слупы, но мало не покажется.

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

Нет, многим, возможно, никогда не потребуется лепить управление очередями, алгоритмы множественного доступа или маршрутизации — но когда за это пытаются браться «чистые айтишники», получается крайне печально. Скажем, посмотрел на днях на Meshtastic — протокол организации mesh-сетей на основе «физики» LoRa. Мало того, что сам по себе протокол толком не документирован — так еще и реализация производит впечатление «слышали звон, да не знают, где он». Элементарнейший пример — используемый алгоритм конкурентного доступа явно сделан «по мотивам» используемой в WiFi distributed coordination function, которая неплохо обоснована с теоретической точки зрения — но упрощен настолько, что утрачена вся суть исходного алгоритма. Да, он выглядит довольно просто — но за этой простотой стоит довольно строгий анализ, и «лишнего» в нем нет. Вишенка на торте — этот важнейший элемент протокола нигде толком не документирован, и для того, чтобы понять, как он работает, приходится лезть в исходники.

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

Про google-driven programming

Вообще я конечно догадываюсь, как обиженка из предыдущей записи нашел мой блог — в интернетах катастрофически мало написано про 6LoWPAN поверх Bluetooth Low Energy, а в особенности — с использованием RIOT OS (кажется, кроме нескольких абзацев официальной ридмишки, которая тоже не дает ответов на все вопросы, ничего толкового нет). Ну чтож, будем помаленьку исправлять.

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

Казнить нельзя помиловать

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

Где-то месяц назад wannabe-программисту встраиваемых систем была выдана не очень сложная задача — разобраться чуть-чуть с сетевым стеком 6LoWPAN over BLE в RIOT OS, немножко автоматизировать его работу и все такое прочее.

Три недели назад чуваку был задан вопрос: все ли просто, все ли понятно, нет каких-либо вопросов? Ответ — разумеется, все просто, все понятно, вот прямо сейчас все сделаю!

Еще неделю спустя задача не выполнена, зато чувак объявился с великолепной идеей — а давайте перейдем на mbed OS, уж там-то все точно просто и понятно, вот даже API References and Tutorials подробные есть (но работает это поверх «обычного» IEEE 802.15.4, а не моднейшего BLE)! Это уже не «звоночек», это гораздо хуже — но в общем сроки пока не горят, ничего ужасного не произойдет, если он недельку потыркается в mbed, нужного там не обнаружит и с позором вернется туда же, откуда начал.

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

В 0:22 в ночь перед небольшим «интеграционным тестированием» системы в чатик прилетает вопрос в духе «а как какать»? По-хорошему, такой вопрос должен был возникнуть еще четыре недели назад — но не будем о старых обидах. Тут, конечно, повезло, что я чатик еще читал — так что в 4:44 в гит-репозитории проекта появилось решение где-то половины той задачи, состоящее из какой-то адовой копипасты и собственного кривого кода arduino-style.

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

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

Ебаный блядский андроид

Изучаю тут реализацию 6LoWPAN over BLE для Android, выяснилось следующее:

— в 7 и 8 версиях есть недокументированный способ открыть сокет уровня L2CAP (через джавовскую рефлексию, описано в дипломной работе этого самого Wieland’а), в 9 версии рефлексия для некоторых «системных» классов запрещена (в том числе и для BluetoothDevice), в 10 версии это API сделано публичным;
— начиная с 6 версии Android не дает узнать MAC-адрес «своего» Bluetooth-адаптера, обходные пути нагугливаются на стековерфлоу, но постепенно закрывались гуглом, начиная с версии 8.1 закрыты все;
— MAC-адрес постоянно и непредсказуемо меняется ради «прайваси» пользователя;
— для того, чтобы начать сканирование BLE-устройств, надо включить «геолокацию», что неудобно для пользователя и в принципе выглядит подозрительно (тут у нас приложенька для фитнесс-браслета, нахуя ей геолокация?).

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

Вдогонку предыдущему — про психопатов

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

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

Ну и на закуску — изрядный портрет этого вашего «айти-специалиста» из одной хорошей книжки:

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

Про опенсорс и айтишников-обиженок

Весь день сегодня обсуждают выходку одного американского программиста, автора двух джаваскриптовых библиотек, который обиделся на весь мир, а особенно на компании из Fortune 500, использующие эти библиотеки — и подумать только, неспособные предложить непризнанному гению скромную six-fugure salary! Что же сделал непризнанный гений? Да просто испоганил эти библиотеки, «сломав» тысячи использующих их приложений (а в мире современной так называемой «разработки» принято подтягивать зависимости из этих ваших интернетов):

https://www.bleepingcomputer.com/news/security/dev-corrupts-npm-libs-colors-and-faker-breaking-thousands-of-apps/

Обсуждать действия чувака неинтересно, ну разве что в порядке наброса сообщу, что он одним-единственным коммитом наработал на 273 статью УК РФ (да, я серьезно, его можно привлечь по российским законам вот прямо сейчас, внимательно читайте статью 12, пункт 3). Неинтересны и способы защиты от таких обиженок — каждому, у кого в голове что-то покрепче творожка, должно быть понятно, что тащить зависимости из интернет-помоек можно только в том случае, если финальный результат вас мало волнует.

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

В «большом» мире все как раз более-менее гладко и понятно — сложились какие-то адекватные модели поведения в диапазоне от «наши штатные сотрудники на зарплате с 9 до 18 работают над linux kernel» до «я ученый, я пишу статьи, а с кодом делайте что хотите», есть более-менее внятные модели заработка на опенсорсе — от платной поддержки до «коммерческого» форка. А вот в мире мелких npm-овских библиотек так и живет эта самая мифология об «энтузиастах». Впрочем, это не мешает «энтузиастам» и их единомышленникам всячески плакать в духе «если бизнес использует наш опенсорс, он должен нам донатить!» Во-первых, дика сама идея, что пользователи «должны» делать что-то, выходящее за рамки лицензии (никто же не стоял с пистолетом и не заставлял вас выкладывать ваш код под MIT Licence, придуманной совсем для другого?), во-вторых, единственно возможный «вклад бизнеса в опенсорс» состоит в следующем, записывайте:

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

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

И еще про Code of Conduct

Будет и у [info]eddy_em праздник — разработчики Rust посрались по поводу CoC и будет теперь у нас два раста — просто Rust и ПедеRust!

https://habr.com/ru/news/t/590869/

Еще несколько слов про отечественное айти-образование

Я все никак не соберусь и не напишу обещанные «многабукв» про околоайтишное образование — но вот еще маленький фактик в копилку. Как я уже писал, жизнь свела меня с первокурсниками магистратуры одного из считающихся неплохими московских вузов — и тем удивительнее обнаруживать у них катастрофические пробелы в знаниях! Например, на прошлой неделе выяснилось, что многим из них совершенно незнакомо слово «mutex» — хотя казалось бы, что курс под названием «Операционные системы» им читали в бакалавриате. Что должен подумать самоучка, читавший книжки Таненбаума? Неплохо, мы можем говорить на одном языке!

Но нет, «Современные операционные системы» Таненбаума включены в программу того курса лишь как необязательное дополнительное чтение, лектор рассказывает в основном об администрировании ALT Linux, а рекомендованный учебник пестрит определениями вроде «Менеджеры ресурсов: этот слой состоит из мощных функциональных модулей, реализующих стратегические задачи по управлению основными ресурсами вычислительной системы» (и как подсказывает коллега [info]matritcasiberia, это «определение» является общепринятым в российском образовании). Определение шикарно в своей бессмысленности — впрочем, подозреваю, что родилось оно из обвешивания прилагательными вполне невинной фразы «Этот слой состоит из модулей, управляющих ресурсами системы». Если «вычислительная система» еще как-то сюда вписывается, то пояснить, чем «мощные функциональные модули» отличаются от не мощных и тем более от немощных не смогут, наверное, даже авторы учебника (или многих учебников — фразочка растиражирована буквально в каждой «рекомендованной» минобразования книге!).

Естественно, «выхлоп» от подобного ПТУшного (и даже хуже) курса в вузе — примерно нулевой. Даже навыков администрирования ALT Linux не хватает, например, для понимания несложных инструкций по работе в консоли Ubuntu, а о вопросах, имеющих отношение к функционированию ядра ОС и даже простых многопоточных программ (что такое планировщик? зачем нужны примитивы синхронизации?) студенты не имеют вообще никакого представления.

Возникает вопрос — а зачем тратить четыре года жизни в бакалавриате, когда иной «колледж» (читай, ПТУ) за три года научит гораздо лучше?

Introduction to Embedded Systems — A Cyber-Physical Systems Approach

Прекрасная, просто замечательная книжка.

Во введении и первой главе наивного читателя заманивают рассказами про «интернет вещей», «киберфизические системы», «индустрию 4.0» и прочий набор стандартных баззвордов. Читатель уже ждет, когда же ему расскажут про то, как на Ардуине и Распберри сделать очередной умный дом — но тут же в главе 2 ему выкатывают второй закон Ньютона, на пальцах объясняют кусочки термеха, пишут всякие дифференциальные уравнения, а немногих выживших добивают преобразованием Лапласа. Дальше, конечно, становится немного полегче, всякая там дискретная математика и конечные автоматы особого полета фантазии не требуют, а местами даже предлагают написать немного кода на Си. Перевернуть свое представление о встраиваемых системах можно по ссылке:

https://ptolemy.berkeley.edu/books/leeseshia/

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

Теоретикам и практикам контроля версий

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

— схемотехника и печатная плата нескольких похожих устройств, библиотека компонентов для Eagle или DipTrace;
— прошивки — несколько, своя для каждого устройства (скорее всего, на базе Riot OS или Contiki, и возможно, с доработками самой ОС — то есть с ней обычно притаскивают целиком ее репозиторий);
— приложение для Android или какой-то там Progressive Web App;
— вебовский бекенд (скорее всего, на Django).

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

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

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

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

Лежит файл, в том файле SQL-дамп, в SQL-дампе поле с JSON, в JSON-е NaCl-овский криптоконтейнер, в криптоконтейнере protobuf, а в protobuf’е смерть Кащеева.

И еще сказочка про выборы и ленивого программиста

Люблю я истории про O(N²), ничего не могу с собой поделать. Так как в этот раз все пока что держится на слухах — пусть это будет сказочка про республику Анчурия, где-то в Латинской Америке.

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

Одного не знали бедные любители высоких технологий из Анчурии — писал ту голосовалку не очень образованный программист Вася, и время подсчета результатов в той голосовалке зависело от количества избирателей квадаратично. Но Министерство Информационных Технологий Анчурии — люди прошаренные, и даже провели тестовое голосование — выбирали, что лучше, леденцы с ментолом или менты с леденцами. В голосовании приняли участие самые прошаренные граждане Анчурии, коих набралось аж 10 000, результаты подсчитались достаточно быстро — и систему решили внедрить на будущих парламентских выборах с десятью миллионами избирателей.

И вот поздно вечером в воскресенье закрылись электронные избирательные участки, и сам Министр Информационных Технологий нажал на самом мощном компьютере Анчурии кнопочку Enter, запустив процедуру подсчета. Долго ли ждать результатов? Ну полчаса-час, ответил министр — и все решили подождать. Сначала два часа ждали, потом четыре, восемь… — в общем, и к утру не дождались. Зато проснулись коммунисты и с криком «Дурят капиталисты нашего брата!» собрали митинг на Главной площади. К вечеру собрался уже не митинг, а целый майдан, кто-то обозвал цифрового министра пiдрахуем (не обошлось без украинского следа), пираты подрались с коммунистами, жулики с ворами — но все вместе пошли от Главной площади по Главной улице к Президентскому дворцу (география столицы Анчурии проста и понятна).

Ну дальше как всегда — Эль Президенте почуял, что пахнет жареным, и сбежал, в Анчурии случилась маленькая гражданская война, к власти пришла военная хунта и от греха подальше запретила все выборы, компьютеры и на всякий случай — украинский язык. Жуликов посадили, воров постреляли, пиратов развесили на реях, коммунистов отправили в тайные тюрьмы ЦРУ. Говорят, что где-то в начале гражданской войны бывший министр даже вылез из своего дата-центра в подземном бункере со словами «Мы все посчитали!» — но всем это было настолько безразлично, что никто про него и не вспомнил.

Так вот, господа программисты, вся беда случилась из-за того, что случайно найденная на гитхабе голосовалка имела сложность подсчета голосов O(N²) — то есть если для подсчета 10 000 бюллетеней требовалась всего 1 секунда — то подсчет 10 000 000 бюллетеней занял не 1 000 секунд, как надеялся цифровой министр, а гораздо больше — 1 000 000 секунд, или целых 11 дней — как раз хватит на то, чтобы не дождавшиеся итогов выборов анчурийцы начали гражданскую войну. O(N²) — очень «хорошая» оценка сложности, она, с одной стороны, достаточно мала, чтобы успешно проходить тесты на небольших наборах данных (это вам не перебор всех подмножеств, и даже не какие-нибудь числа Белла) — а с другой стороны, очень плохо ведет себя, когда данных становится много.

А чтобы не спровоцировать гражданскую войну в латиноамериканской стране — не делайте алгоритмы со сложностью O(N²), а читайте книжки Скиены, Седжвика, Дасгупты и Кормена, можно еще поставить на полочку многотомник Кнута.

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

На днях в твиторе срались, может ли программистская контора держать свой код на гитхабе, или это стыдно. А я вот подумал — есть ли что-то стыдное в том, что у той же конторы сайт будет на narod.ru и почта на mail.ru?

Скатываясь в глубины безумства

Заменил Word и Excel на latex с gnuplot. В планах полностью автоматизировать построение некоего документа с текстом и графиками. Когда меня отправят в дурку?

Вытащу из фейсбука

А то скоро придется снова этот стенд собирать, а ответов на вопрос, кроме как «фронтендеры петухи», у меня как бы и нет.

В общем, есть дохлый по современным меркам Raspberry Pi, на нем крутится две или даже три СУБД (постгрес, монго и кажется, mosquitto еще что-то свое притаскивал), сетевой сервер LoRaWAN (ChirpStack, если это кому-то что-то говорит), Influx DB и Grafana, а рядом стоит ноутбук, на котором запущен SDR Sharp и браузер, а в браузере крутится веб-интерфейс этого чирпстека. Так вот, зоопарк (написанный в основном на няшной сишечке и модном голанг) на распберри работает прекрасно, написанный на С# SDR-приемник крутит какие-то адовы преобразования Фурье и показывает красивые картинки, отжирая всего-то несколько сот мегабайт памяти и 10-15% процессора, а вот веб-интерфейс, написанный на прекрасном современном языке Javascript, выполняющий важную задачу — показать в окошке браузера несколько плашечек вида «куда-кому-от кого», на сотне-другой этих плашечек начинает жрать буквально гигабайты памяти и так грузить процессор, что я даже не могу представить, куда идут эти бешеные FLOPSы (а это все-таки Core i5, не херня какая).

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

А как это называется?

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

Волшебные константы, часть 2

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

Хотя… Пожалуй, обсуждать, по какой причине господин Mathieu Lacage старательно расписал enum для разных значений SUBTYPE_CTL_*** и не стал так делать для SUBTYPE_MGT_*** и SUBTYPE_DATA_*** будет довольно скучно (ответ: потому что мудак), а было бы забавней обсудить, как и почему для того, чтобы два байта отослать — я не вру — вот эти два байта октета:

— надо городить аж вот такую фигню:

uint8_t m_ctrlType;     ///< control type
uint8_t m_ctrlSubtype;  ///< control subtype
uint8_t m_ctrlToDs;     ///< control to DS
uint8_t m_ctrlFromDs;   ///< control from DS
uint8_t m_ctrlMoreFrag; ///< control more fragments
uint8_t m_ctrlRetry;    ///< control retry
uint8_t m_ctrlMoreData; ///< control more data
uint8_t m_ctrlWep;      ///< control WEP
uint8_t m_ctrlOrder;    ///< control order

Вообще, я видел три подхода к проблеме заполнения всякого рода "предопределенных" байтовых и битовых структур на C и C++. Подход первый, расточительный, продемонстрирован только что - заводим по полю избыточного, но удобного размера на каждый элемент структуры, а затем пишем две функции Serialize и Deserialize, в которых занимаемся странным байтоебством примерно в таком духе (да, волшебных констант тут налепили много):

uint16_t val = 0;
val |= (m_ctrlType << 2) & (0x3 << 2);
val |= (m_ctrlSubtype << 4) & (0xf << 4);
val |= (m_ctrlToDs << 8) & (0x1 << 8);
val |= (m_ctrlFromDs << 9) & (0x1 << 9);
val |= (m_ctrlMoreFrag << 10) & (0x1 << 10);
val |= (m_ctrlRetry << 11) & (0x1 << 11);
val |= (m_ctrlMoreData << 13) & (0x1 << 13);
val |= (m_ctrlWep << 14) & (0x1 << 14);
val |= (m_ctrlOrder << 15) & (0x1 << 15);
return val;

Вариант второй - экономично-эмбеддерский, выглядит примерно так:

uint16_t frameControl = 0;
frameControl |= (CTL_TYPE_DATA << FRAME_CONTROL_CONTROL_TYPE_OFFSET) & FRAME_CONTROL_CONTROL_TYPE_MASK;
frameControl |= (CTL_SUBTYPE_DATA_QOS << FRAME_CONTROL_CONTROL_SUBTYPE_OFFSET) & FRAME_CONTROL_CONTROL_SUBTYPE_MASK;

ctrlSubtype = (frameControl & FRAME_CONTROL_CONTROL_SUBTYPE_MASK) >> FRAME_CONTROL_CONTROL_SUBTYPE_OFFSET;
/* and so on */

Отличие от предыдущего - мы работаем напрямую с этими двумя байтиками, и это довольно экономично, нам не надо работать с "тяжеловесным" по эмбеддерским меркам объектом с десятком-другим полей, а то и целой ссылкой на vtable (если обратите внимание - функции Serialize и Deserialize виртуальные). Можно обернуть это все в несколько более удобные макросы или inline-функции.

Но неужели для такой стандартной задачи человечество не придумало ничего лучше? Подобного рода херней люди занимаются вот уже несколько десятков лет, и в полувековой давности языке C есть прекрасная штука - битовые поля. В книжке 1984 года The Unix Programming Environment они описывались, как рекомендованный и правильный способ вот этого битоебства. По удобству это напоминает первый способ, с членами структуры, а по экономичности полностью аналогично второму:

struct {
    unsigned int protocolVersion : 2;
    unsigned int type : 2;
    unsigned int subtype : 4;
    unsigned int toDS : 1;
    unsigned int fromDS : 1;
    unsigned int moreFragments : 1;
    unsigned int retry : 1;
    unsigned int powerManagement : 1;
    unsigned int moreData : 1;
    unsigned int protectedFrame : 1;
    unsigned int order : 1;
} frameControl;

frameControl.type = CTL_TYPE_DATA;
frameControl.subtype = CTL_SUBTYPE_DATA_QOS;

ctrlSubtype = frameControl.subtype;
/* and so on */

Но... если на уровне "байтиков" структуры в C и C++ еще как-то предсказуемы (а проблемы с выравниванием обычно решаются с помощью #pragma pack(1)), то вот битовые поля оказываются настолько непредсказуемы, что в книжке Кернигана и Ритчи приведено осторожное предупреждение, а в любом современном учебнике настоятельно рекомендуется ими никогда не пользоваться!

Что-то мне подсказывает, что вовсе не этого хотели Керниган с Ритчи. А что вы порекомендуете?

Давайте поговорим про зарплаты программистов

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

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

Вопрос первый: правильно ли будет поделить сумму поровну, 160/160/160?

Вопрос второй: программисты из твитора рассказывают, что получать меньше одной козули (единица измерения зарплат программистов, 300 тысяч рублей в месяц) стыдно, и приводят в пример одного фронтендера. Не будет ли более правильным платить программисту 320, а тем двум неудачникам — по 80?

Вопрос третий: вы решили строить свой стартап в Европе, пересчитали бизнес-модель и распоряжаетесь ФОТом в 9600 евро. Команда та же, но местные, два инженера и программист. Правильно ли будет платить им 3200/3200/3200?

Вопрос четвертый: европейский программист приходит к вам и говорит, что не согласен работать за 3200, а хочет 6400, потому как в Силиконовой долине за ту же работу платят столько. Чемодан-вокзал-Лос Анджелес или 6400/1600/1600?

Вопрос пятый: расставшись с жадным европейским программистом, вы решили вернуть программирование в Россию. Сколько платить местному программисту: 160, 320 или 256 (примерно 3200 евро) тысяч рублей?