All streams
Search
Write a publication
Pull to refresh
5
0
Send message
Спасибо за ссылку на «Научные основы доказательного программирования».

Ответы на ваши вопросы вполне просты и выводятся из теории рынка: в далёком прошлом ПО писали по-научному; ошибки в программах были, но это именно обычные человеческие опечатки/невнимательность, за каждой программой стояло математическое доказательство её работоспособности. Причины: компьютерное время было в дефиците по сравнению с временем программистов, поэтому запускать ПО с ошибками слишком дорого обходилось. А программистов было слишком мало по сравнению с населением Земли, поэтому порог вхождения был крайне высок (требовалось и знание математики, и машин, и алгоритмов...). Сейчас ситуация обратная: процессорное время слишком дешёво, программистов слишком много, ущерб, который испытывает бизнес от багов в ПО очень низкий, ниже, чем стоимость подготовки команды образованных программистов и их работы. Дешевле запустить 100 000 юнит тестов, чем вычитать код из хотя бы 100 строк и напрячь голову. Таким образом рынок продолжает двигаться и по сей день: программистов становится ещё больше, квалификация их становится ещё ниже, порог вхождения поддерживается на сбалансированном уровне за счёт количества спецификаций, которых надо учить, а ущерб, получаемый корпорациями от багов медленно растёт.

На счёт «изменить ситуацию». Только сегодня закончил исследование по связанной теме. Результат: писать надо на си, без плюсов. Парадигмы высокоуровневых языков огриничивают возможности программиста.
Нашёл, в чём здесь подвох. Создать бинарник, который выполняется в бинарном виде — невозможно. Здесь же другая ситуация.
Вообще, статья больше вводит в заблуждение, чем объясняет. Сначала в ней говорится, что win-заголовок может интерпретироваться как скрипт, причём без шебанга, но в следующем абзаце этот код запускается в двоичном виде. На каком основании? Заголовок ELF должен быть расположен строго в начале файла и нигде более, если его там нет, то программа запускается как скрипт, но она уже запущена как скрипт. То есть вот exec 7<> $(command -v $0) приведёт к бесконечной рекурсии. Ладно, допустим, этот код как-то приыёл к запуску программы в двочином виде. В дебаггере мы видим опять MZ, размещённые по адресу 40000, то есть теперь этот же заголовок исполняется как _start. Отлично. Давайте рассмотрим абстрактную платформу, в которой опкод MZ просто не реализован, и натолкнувшись на него процессор сразу же выдаёт Illegal Opcode Exception, а система радостно грохает процесс.

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

С таким же и даже большим успехом можно было просто написать программу на python. Интерпретатор установлен на системном уровне и в linux, и в последних windows.
Точно. с BigEndian будут проблемы. Но если присмотреться, цикл проверяет, что в блоке нет ни одного нулевого байта, и при смене порядка порядка цикл будет корректно работать. Меняется только действие, когда мы нашли нулевой байт: надо не с конца считать номер байта, а с начала. Но для этого уже предусмотрена другая функция.

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
i += (unsigned)__builtin_ctzll(w) >> 3;
#elif __BYTE_ORDER__ == __BIG_ENDIAN__
i += (unsigned)__builtin_clzll(w) >> 3;
#else
AUCHTUNG!;
#endif

В таком виде Big Engian машинам не придётся за зря крутить байты в строках.
Ассемблерный код оказался более читаемым, чем исходник. То есть вся эта страшная конструкция эквивалентна одному простому mov:
w = ((uint64_t*)(p))[0];
Но почему разработчики не написали именно так?

А алгоритм сводится к битовой магии add, not, add, add.
Блоки по 8 байт, а внутри каждого блока также каждый байт проверяется. Алгоритм опять сводится к тому, что каждый байт проверяется. Получается 28 арифметических операций на 8 байт. Это больше, чем N=3*8=24, не исключено, что такая оптимизация будет даже медленнее.

w = (uint64_t)p[7] << 070 | (uint64_t)p[6] << 060 | (uint64_t)p[5] << 050 |
(uint64_t)p[4] << 040 | (uint64_t)p[3] << 030 | (uint64_t)p[2] << 020 |
(uint64_t)p[1] << 010 | (uint64_t)p[0] << 000;
if ((w = ~w & (w — 0x0101010101010101) & 0x8080808080808080)) {
Если посмотреть на версию из libc, то видны те же два вызова strlen и memcpy. Не с проста это. Дело в том, что эта функция не знает длину исходной строки, в неё передаётся только размер буфера. Поэтому приходится сначала по одному байту искать, где же конец строки, а затем блоками копировать нужную длину (memcpy это умеет).
В первую очередь — подумать, нельзя ли уменьшить число параметров. Но если речь о каком-нибудь специфическом ABI или передаваемом типе данных, то без стека не обойтись.
Допустим, проблема наблюдается при запуске такого приложения на линукс. Устанавливаем Wine, запускаем приложение через него. После пару десятков segfault и подбора параметров запуска добиваемся того, что программа выполняет нужную нам задачу и сваливается с какой-нибудь ошибкой после. Объясняем начальству, что программа задачу выполняет, а появление окошка «приложение будет закрыто» — вам надо, чтобы задачу делало или чтоб красиво было?

Ведь так всё и будет. Точно кто-нибудь, да попадёт на такое.
увы, последние лет 10 бизнес в таких ситуациях призывает далёкого от программирования человека и говорит: «ну сделай что-нибудь с этим, короче, через 15 минут эта штуковина должна зработать», и так рождается очередной костыль/патч/скрипт по перезапуску для какого-нибудь нестабильного продукта.
Теперь хоть что-то стало понятно. Спасибо. Ваш бы комментарий вместо статьи. А какие у вас были ожидания? То, что нельзя создать бинарник, который будет исполняться на всех платформах, без чего-нибудь специально предустановленного для этого, — это математическая теорема. Вопрос лишь в том, чем именно они пожертвовали, пытаясь создать невозможное.
Пусть не изящное, но рабочее решение. Однако это не поможет с тем, что на разных аппаратных платформах (amd64 и тот же arm) одни и те же двочиные коды будут выполнять разные команды. Можно попытаться сделать конструкцию вида SMTSMT; add rax, CONST; jmp rax. Тогда в зависимости от результата выполнения первой команды мы узнаём, на какой платформе работает, затем при помощи add превращаем результат в адрес и делаем jump… но для этого надо чтобы хотя бы jmp имел одинаковые машинные коды…

Нет, всё ещё непонятно.
При помощи заголовка вы добились запуска бинарника на разных ОС. При дальнейшем выполнении кода неизбежно возникают следующие проблемы: системные вызовы windows и linux разливаются и по номерам, и по функционалу, как будут осуществляться системные вызовы в этом бинарнике; различные платформы имеют различные ABI, какое соглашение будет использоваться для передачи параметров в подгружаемую внешнюю библиотеку; на некоторых платформах может быть не быть какой-нибудь инструкции или регистра, которые приведены в в листингах, будет ли работать программа на такой платформе; допустим, самая первая же инструкция pop r10 — если тот же машинный код будет соответствовать какой-нибудь инструкции, то программа даже не запустится?

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

А сейчас так просто взяли и поменяли концепцию. То есть десять лет чеолвечеству было вредно от синего света, начался коронавирус, и всё, теперь не вредно? Это люди изменились, понятие «вред» и «польза» пересмотрели или выяснилось, что предыдущие исследования были недобросовестны?..

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

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

А что касается сжатия… следовало бы сравнивать с возможностями сжатия на уровне ФС. Это удобнее, так как не надо ничего запаковывать/распаковывать, это может быть быстрее за счёт использования инструментов уровня ядра, и это может дать большее сжатие за счёт большего числа файлов. Надо проводить эксперименты.
Первый закон гласит, что тело неподвижно, если на него не действуют силы, а если силы действуют, то см второй закон. Поскольку формула движения в 1-ЗН является частным случаем 2-ЗН при F=0, то по факту речь идёт об одном законе, формула которого приведена во 2-ЗМ, а текстовая формулировка которого включает и 1-, и 2-ЗН. Разделение закона на две части ничем не оправдано, а потому лишено смысла.

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

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

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

Information

Rating
Does not participate
Registered
Activity