Серия «Доступно об АйТи»

Доступно об АйТи: Откуда взялись Meltdown и Spectre

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

Доступно об АйТи: Откуда взялись Meltdown и Spectre Meltdown, Процессор, IT, Spectre, Уязвимость, Длиннопост

Эмблемы уязвимостей Meltdown и Spectre

Извлечением разведывательных данных из открытых каналов шпионы занимались давно. С 2022 очень многие умеют сопоставлять снимки местности с гуглокартами (я не умею). И потому считается, что любое военное фото и видео лучше выкладывать несколько дней спустя, когда извлечённая информация будет неактуальной. И именно это — утечка данных через открытый канал — случилось почти со всеми x86. К Meltdown были уязвимы все Intel начиная с Core, к Spectre — вообще все.

Вкратце о виртуальной памяти. Появилась на процессоре 80386 (1985), даёт каждой программе подобие выделенного процессора с 4 гигабайтами памяти (если процессор 32-битный). Таблицы преобразования из виртуальных адресов памяти (доступных программисту) в физические (какая ячейка ОЗУ) находятся всё в том же медленном ОЗУ.

Доступно об АйТи: Откуда взялись Meltdown и Spectre Meltdown, Процессор, IT, Spectre, Уязвимость, Длиннопост

Приблизительное устройство виртуальной памяти

Программе иногда приходится обращаться к функциям ОС — например, чтобы получить имя текущего пользователя. Эта функция обязана обращаться и к системной памяти (там находится имя), и к пользовательской (чтобы скопировать имя туда). Решено это так: часть системной памяти внесена в виртуальную память программы, но доступ к ней разрешён только из системных функций. Именно эту память, которую «видит око, да зуб неймёт», читает Meltdown. Отсюда название — эта уязвимость «плавит» границы памяти.

Закон дырявых абстракций

Чтобы прочитать эту память, нужны определённые технологии процессора.

  • Чтобы поменьше обращаться к медленному ОЗУ, у процессора есть быстрая маленькая кэш-память. У современных процессоров есть три уровня кэш-памяти, нас интересует кэш 1-го уровня (ближайший к процессору, несколько килобайт объёмом, работает не с физическими адресами памяти, а с виртуальными).

  • Процессор умеет выполнять операции наперёд. Но в любой программе есть команды ветвления — скажем, «если D<0, то уравнение решения не имеет, иначе корни такие-то». Все современные x86 ещё до того, как вычислят D, пробуют пройти по одной из веток (а то и по обеим).

  • При этом процессор не знает наперёд, имеет ли он право выполнять эту операцию: для этого надо заглядывать в таблицы преобразования, а они если не в оперативной памяти, то в особом кэше преобразования адресов, который сидит между 1-м и 2-м уровнями. Так что просто выполняет — а потом уже разбирает, имеет ли он право это делать.

  • Для высокоточного отсчёта времени (для мультимедиа, игр и прочего) в процессоре есть счётчик тактов.

Джоэль Спольский придумал так называемый «закон дырявых абстракций». Звучит он примерно так:

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

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

Дисклеймер: я о традиционной коробке типа «гидроавтомат» без электронных помощников. Да простят меня обладатели вариаторов и роботов.

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

  • Чем выше оказалась случайно стрелка тахометра в момент T, тем лучше тянет машина, если резко нажать газ.

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

  • Ну и целая куча тонкостей в сложных и экстремальных режимах езды.

Как работает Meltdown

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

Сбросить кэш-память

Если некое условие (гарантированно не выполняющееся)

……Считать число из запретного адреса

……Извлечь из числа один бит (то есть 0 или 1)

……Загрузить из массива элемент № (бит·1000) — то есть № 0 или № 1000

Иначе

……Загрузить из массива элемент № 0, измерить время доступа

……Загрузить из массива элемент № 1000, измерить время доступа

Условие гарантированно не выполняется, но надо заставить процессор пройти наперёд именно по первой ветке — и он выполняет её наперёд, не зная, что адрес запретный. Заодно перекидывая элемент № 0 или № 1000 в кэш. Массив длинный, оба сразу в кэш не попадут.

Если из запретного адреса считан 0, доступ к элементу № 0 будет быстрым (он в кэше), а к элементу № 1000 — медленный. И наоборот.

И так бит за битом читают запретную память.

Spectre

Сбросить кэш-память

Если некое условие (гарантированно не выполняющееся, с доступом к ОЗУ)

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

……Извлечь из числа один бит (то есть 0 или 1)

……Загрузить из массива элемент № (бит·1000) — то есть № 0 или № 1000

Иначе

……Загрузить из массива элемент № 0, измерить время доступа

……Загрузить из массива элемент № 1000, измерить время доступа

Самый известный вариант Spectre очень похож на Meltdown, и главная разница такова: а) мы хотим получить доступ к памяти другой (атакуемой) программы, и мы знаем желаемый адрес в её виртуальной памяти; б) атакуемая программа постоянно имеет дело с этим адресом — и потому секретный байт в кэше (напоминаю, кэш 1-го уровня имеет дело с виртуальными адресами); в) «некое условие» вычисляется по формулам, требующим доступа к ОЗУ; г) запретный адрес тоже вычисляется по формулам, но более простым и быстрым.

Следите за руками. Не видя способа быстро рассчитать условие, процессор начинает наперёд крутить ветку «то». Вычисляет адрес, считывает из него число, а пока оно ползёт из ОЗУ, пробует прокрутить следующие шаги с тем числом, что завалялось в кэше . Число из ОЗУ не успеет прийти («если некое условие» будет вычислено раньше), но эти шаги, опять-таки, приведут к тому, что либо № 0, либо № 1000 будет закэширован и доступ к одному будет быстрый, а к другому — нет.

Название Spectre («призрак») происходит из-за крайней сложности ошибки (уязвимы почти все x86, программно не закрывается, и ожидалось, что она ещё некоторое время будет преследовать) и технологии «выполнение наперёд» (speculative execution).

К чему это привело

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

Разработчики браузеров внесли свою лепту — дело в том, что в современном браузере JavaScript частично компилируется в машинный код! И они подкорректировали компиляцию так, чтобы шансы на удачную эксплуатацию были минимальны.

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

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

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

Показать полностью 2

Доступно об АйТи: Почему винил звучит богаче, чем CD?

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

Доступно об АйТи: Почему винил звучит богаче, чем CD? Вопрос, Грампластинка, Виниловые пластинки, Компакт-диск, Аудиотехника, Видео, YouTube, Длиннопост

Весёлые CD-болванки производства Verbatim

Копипаста из «Вокруг света»

Дело в сохранности оригиналов. При прочих равных цифровой звук CD-качества по всем параметрам превосходит аналоговые записи на виниле. Однако редко удается сравнить записи, произведенные в одинаковых условиях. Например, пластинки групп 1960–70-х делались со свежих студийных мастер-лент и могут звучать лучше CD, которые изготавливались позже с уже изношенных оригиналов, а то и с виниловых пластинок.

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

…Но это не только! Моё дополнение

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

Цифре всё едино, покуда пики вписываются в диапазон от −100% до 100% — но если из-за цифровой обработки они выйдут за диапазон, будет так называемое цифровое запирание, не любимое никем и звучащее как треск.

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

Для изготовления рингтонов, которые должны быть громкими на ОЧЕНЬ плохом динамике, музыку прогоняют через сильный компрессор.

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

Шумы старой аппаратуры также вносят свою лепту во впечатление от музыки — особенно если там мало инструментов.

Показать полностью 1 3

Доступно об АйТи: Почему Буш скрыл факты?

Я сейчас опишу две старых фишки программ Microsoft — одна ошибка, а другая просто старый мем.

Bush hid the facts

Доступно об АйТи: Почему Буш скрыл факты? Баг, IT, Русский язык, Unicode, Грамматические ошибки, Windows XP, Microsoft Word, Длиннопост

Как повторить: на Windows линейки NT, до XP включительно, написать в Блокноте «Bush hid the facts» и сохранить файл. При открытии получим китайские иероглифы — или тофу («квадратики»), если в системе нет китайского шрифта. Другое ПО (например, WordPad) показывает, что файл в полном порядке.

Мем появился при Буше-младшем, но ошибка появилась в 90-е, вскоре после правления Буша-старшего. И заключается она вот в чём.

Долгое время символ текста совпадал с байтом — минимальной единицей памяти и телекоммуникаций. Разных байтов всего 256, этого хватает на английский и местный язык. И даже если местный язык всего один (например, русский/украинский), появилось множество разных кодировок, призванных обойти важные символы той или иной базовой кодировки. Так, в кодировке DOS (=CP866) обходили псевдографику, в кодировке Windows (=CP1251) — типографские символы и управляющий знак «мягкий перенос», кодировку КОИ-8 подгоняли под старое почтовое ПО, убиравшее верхний бит. И появился термин крокозябры — текст не в той кодировке.

Доступно об АйТи: Почему Буш скрыл факты? Баг, IT, Русский язык, Unicode, Грамматические ошибки, Windows XP, Microsoft Word, Длиннопост

А уж сложный текст (например, по языкознанию), содержащий санскрит и древнерусский ять ѣ, так вообще не напишешь. И тогда в начале 90-х придумали Юникод, тогда ещё просто двухбайтовую кодировку — один символ кодируется двумя байтами. Windows NT изначально писалась юникодной, и там появилась функция IsTextUnicode, проверявшая статистикой, чем, скорее всего, является строка байтов — текстом в однобайтовой кодировке или текстом в Юникоде. Функция существует и поныне, однако Блокнот её давно не использует.

Статистика была проста: длина строки чётная, и чётные байты меняются значительно меньше, чем нечётные. Так что к ложным срабатываниям приводят строки «hhhh hhh hhh hhhhh» и «this app can break».

Хочу избежать службу в армии

Доступно об АйТи: Почему Буш скрыл факты? Баг, IT, Русский язык, Unicode, Грамматические ошибки, Windows XP, Microsoft Word, Длиннопост

Как повторить: на старых версиях Word с русским словарём производства «Информатик» включить проверку грамматики и написать: «Хочу избежать службу в армии». И смотреть, что она выведет.

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

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

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

  • согласование: слова изменяются синхронно: чёрный хлеб, чёрного хлеба.

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

Показать полностью 2

Доступно об АйТи: Почему полоса прогресса ходит неравномерно

Ну вот и я подключусь к волне постов и расскажу кое-что на этот счёт.

Доступно об АйТи: Почему полоса прогресса ходит неравномерно IT, Волна постов, Интерфейс, Программирование, Длиннопост, Progress bar

Кто виноват и что делать? И кому на Руси жить хорошо?

Опять для Лиги лени поставлю телегу впереди лошади.

Сначала отвечу на третий вопрос — хорошо начинающим программистам, ведь современные библиотеки позволили очень маленькой кровью, например, загружать сайт, а потом извлекать из него информацию. Чтобы загрузить страницу, можно просто исполнить программу cURL, которая есть в Windows 10 начиная с патча 1803, а в *nix — была с давних пор.

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

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

И оглавление, снова для Лиги лени.

  1. Иногда ей надо ходить неравномерно.

  2. Загрузка — сложный процесс.

  3. Обратная связь — затратная операция.

  4. Иногда программа не может вызвать обратную связь.

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

Пристёгивайтесь, поехали!

Иногда ей надо ходить неравномерно

Пример: торрент-клиент

Доступно об АйТи: Почему полоса прогресса ходит неравномерно IT, Волна постов, Интерфейс, Программирование, Длиннопост, Progress bar

Что происходит, когда мы скачиваем файл по протоколу распределённой закачки? (Считаем, что интернет хороший.)

  1. Клиент обращается к трекеру (или бестрекерной сети), чтобы найти тех, у кого этот файл есть. И заодно сам объявляет трекеру, что мы этот файл хотим. Прогресс стоит.

  2. Потихоньку сползаются раздающие — поползли по сети первые блоки. Прогресс разгоняется.

  3. Скорость дошла до предела, предлагаемого нашим провайдером или найденными раздающими — прогресс идёт равномерно.

  4. Файл скачан почти весь, докачиваются последние блоки. Часть раздающих отключаем, скорость падает — прогресс замирает на 99%.

  5. Скачан самый слоупочный блок — всё, 100%!

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

Загрузка — сложный процесс

Пример: любая игра или инсталлятор

Доступно об АйТи: Почему полоса прогресса ходит неравномерно IT, Волна постов, Интерфейс, Программирование, Длиннопост, Progress bar

Пример с торрент-клиентом я уже привёл. Посмотрим, что творится в любой игре.

  • Загрузка из интернета — зависит как от пинга к серверу, так и от скорости этого самого интернета.

  • Доступ к файлам — на SSD почти мгновенный, на механическом диске — ощутимую долю секунды.

  • Линейное чтение файла — зависит от скорости диска.

  • Распаковка файла (почти всегда игра сжата каким-нибудь ZIP’ом) — тут уже действует процессор.

  • Передача распакованного в видеопамять — подключается видеошина.

Будь у нас компьютер с полностью стандартным железом, на манер ZX Spectrum, всё было бы понятно. Но ведь IBM стали стандартом именно потому, что имели множество разных процессоров, дисков и другой аппаратуры, от дешманских до high-end. А интернет-соединение вообще никак и нигде не стандартизировано.

Один из разработчиков сказал: «вот в этой точке мы перемещаем прогресс на 20%», что это значит? Он сидел с часиками и смотрел на отладочный вывод, и понял, что вот этот шаг отнимает примерно 20% времени. Примерно: на другой машине это может быть 10 или 30%. У разработчика — любого — есть один перекос: они пользуются мощными машинами, и потому отмеренные 20%, скорее всего, будут относиться именно к мощному компу.

А это уже личный опыт. Загрузку игры на Java ME я делил на 10–20 примерно одинаковых шажков. Это могла быть загрузка графики, тригонометрических таблиц, спрайтовых таблиц и много чего ещё. Показывается заставка разработчика/распространителя — игра грузится, но прогресса пока нет. Показывается заставка игры — прикидываем процент загрузки, и делаем одно из трёх.

  • Игра под заведомо быстрый мобильник (Nokia Series 40, Sony Ericsson серий K и Z) — нет индикатора. В таких портах на заставке даже нет места под индикатор.

  • Игра прикидывает, что загрузка закончится за те минимум 2,5 секунды, что отданы на заставку — тоже нет индикатора.

  • Или всё-таки рисует индикатор, но он идёт от 0 до 100%, даже если за время первой заставки игра ухитрилась проскочить 4 шажка из 12. Если оставшиеся восемь проскочила со скоростью звука — всё равно заставка висит минимум 2,5 секунды, с прогрессом 100%.

Обратная связь по прогрессу — затратная операция

Когда я пришёл в ту контору, писавшую игры для мобильников, их игры могли грузиться минуту и более. На Nokia Series 60, которая тогда была базовым портом! Перестав дёргать прогресс без нужды, мы ту же S60 отнесли к «условно быстрым» — какие-то телефоны ухитрялись всё загружать за пять-шесть секунд заставок, какие-то чуть дольше.

Давайте о том, как можно обеспечить обратную связь на ПК под управлением Windows (о других ОС не знаю).

  1. Самый технически простой. Ничего не делать, только грузить, иногда на короткие моменты передавая управление главному окну. Грузит и рисует полностью последовательно: пока окно перерисовывается, загрузка не идёт. Игра выглядит «застрявшей», не реагирует на управление, ОС может даже сказать: программа не отвечает, хотите дождаться?

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

  3. Этот способ самый сложный, но и самый быстрый. Загрузчик кладёт информацию в «почтовый ящик». Главное ядро время от времени этот ящик трясёт — и выводит его содержимое. Если в ящике всего одна цифра, это очень просто — 4 или 8 байт, в зависимости от архитектуры процессора, перейдут от процессора к процессору неиспорченными. Но с более сложной отладочной информацией надо неплохо так заморочиться, чтобы этой порчи не было — и чтобы не было того, что грузит и рисует последовательно (см. 2).

Доступно об АйТи: Почему полоса прогресса ходит неравномерно IT, Волна постов, Интерфейс, Программирование, Длиннопост, Progress bar

💽 грузить, 🖌️ рисовать, ⚙️ отрабатывать сообщения Windows, ⬛ обмен данными, 🚬🎋 простаивать

Иногда программа не может вызвать обратную связь

Пример: копирование в Windows на флэшку

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

Чем отличается копирование на винчестер (нет защиты от небезопасного извлечения) от копирования на флэшку (таковая есть)? Последним шагом, закрытием файла! Если копирование на винчестер, пользователь уже получил управление, но Windows ещё несколько секунд трещит, сбрасывая данные на диск — на флэшке сброс идёт сразу при закрытии, ведь надо защитить флэшку от небезопасного извлечения! Минуту, без всякой обратной связи.

Иногда обратную связь вызвать архитектурно сложно

Пример: последние шаги большинства инсталляций или расчётов

Вот поэтому прогресс часто зависает на 100%. Система бывает просто не приспособлена, чтобы запускать эти последние шаги на другом процессоре. Удаление временных файлов, перерисовка пользовательского интерфейса, дополнительные мини-расчёты, которые выполняются с каждым кликом мышью…

Эти шаги можно загнать под прогресс, но это требует непропорционального объёма программистской работы.

Показать полностью 3

Доступно об АйТи: Почему не взлетели визуальные языки

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

Доступно об АйТи: Почему не взлетели визуальные языки Программирование, IT, Языки программирования, Визуальное программирование, Длиннопост

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

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

  1. Там, где действительно клик выразительнее текста.

  2. Чтобы как-то привлечь к программированию посторонних.

Клик выразительнее текста

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

Редактор форм типа Embarcadero Delphi и Qt Creator.

Доступно об АйТи: Почему не взлетели визуальные языки Программирование, IT, Языки программирования, Визуальное программирование, Длиннопост

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

Любая реляционная СУБД (система управления базами данных традиционного типа с таблицами и ключами), где линиями удобно показывать взаимоотношения между таблицами.

Доступно об АйТи: Почему не взлетели визуальные языки Программирование, IT, Языки программирования, Визуальное программирование, Длиннопост

Программирование для посторонних

Иногда удобно привлекать к программированию специалистов в своей сфере — трёхмерщиков, геймдизайнеров, экономистов. Пусть они плохо программируют, зато свои знания успешно применят. Вот, например, редактор материалов из Unreal.

Доступно об АйТи: Почему не взлетели визуальные языки Программирование, IT, Языки программирования, Визуальное программирование, Длиннопост

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

Доступно об АйТи: Почему не взлетели визуальные языки Программирование, IT, Языки программирования, Визуальное программирование, Длиннопост

А с профессионалами ответа два.

  1. Вы просто не знаете, чем занимается программист.

  2. Существует очень много специального ПО, ориентированного на текстовые файлы.

Так чем же занимается программист?

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

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

  1. Программист разделит игру (на чужом движке) на две части: 1) Управление игровой физикой; 2) Общий цикл игры (скобку «forever»), который отвечает за условия выхода из игры, вызовы игровой физики и прорисовщика, ограничение кадровой частоты.

  2. Почему скорость персонажа в 10 пикселей/кадр жёстко прописана? Не лучше ли указать где-то: СКОРОСТЬ_ПИНГВИНА = 10?

А если игра будет управляться и клавиатурой, и джойстиком — программист напишет (или сдерёт) общий «центр управления», а затем будет спрашивать у него: нажата ли кнопка «двигаться вправо»? А уж что это — клавиша →, или D, или ось X джойстика, или крестовина вправо — это дело того самого центра управления.

В тех же «Космических рейнджерах» нередко нарушается знаменитый программистский жупел — «не повторяйся». Например, в игре в кости первый раз результат разыгрывается как [2..12], а дальнейшие — [1..6]+[1..6]. Программист напишет так, чтобы первая и последующие партии управлялись одним и тем же кодом.

Чем хороши текстовые файлы?

Существует широкий набор утилит для работы с текстовыми файлами:

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

  • В них можно искать файловыми менеджерами.

  • Работу нескольких человек можно объединять с помощью систем управления версиями.

И всё это нужно программистам. Даже XML снижает полезность этих инструментов.

Показать полностью 4

Как устроены эмодзи

Эмодзи (от японского «э» — картинка и «модзи» — знак) — язык пиктограмм, используемый в текстовых сообщениях. Будем говорить исключительно об эмодзи Юникода, как о самых распространённых.

История

В некоторых компьютерах мордашки включали в наборы символов: так, у компьютеров IBM (1981) две мордашки имели коды 1 и 2. Но пользоваться ими проблематично: их нет на клавиатуре, привязаны к платформе, да и коды 0…31 часто имеют собственное управляющее значение.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Смайлик :-) придумали на заре Интернета, в 1982 году.

Конец 1990-х. Везде графика, и в различных системах интернет-общения появилась функция: отыскать в тексте :-) и заменить графической рожей. Кто помнит этот стиль смайликов?

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

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

Было время, когда SMS’ки стоили дорого, и мы экономили символы. Экономили и японцы, и мобильный оператор DoCoMo в 1999 придумал вот такие символы, их и назвали «эмодзи». Кодировка символов собственная докомовская.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

В середине 2000-х годов смайликами обзавелись как Гугл в своей почтовой службе, так и Эпл в айфонах. Возник вопрос межплатформенного обмена смайликами, и консорциуму Юникода в 2010 году осталось только возглавить бардак, который они не в силах предотвратить, тем более свободных позиций в Юникоде всё ещё предостаточно: в ожидаемом Юникоде 15.1 пока 150 тысяч символов из 900 тысяч доступных. Добавляли понемногу, по несколько сотен, пока около 2018 не добавили все.

Совет: мало кто знает клавишу Win+; (точка с запятой) или Win+. (точка) из Windows 10+. Она выводит панель символов, в том числе эмодзи.

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

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

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

А пока…

Немного теории

Символом будем называть всё, что есть в кодировке: печатаемые символы, управляющие команды, незанятые позиции…

Любая кодировка заключается в замене символов на кодовые последовательности: например, пробел=32, A=65, B=66… Но Юникод пошёл дальше: как только символ попадает в Юникод, ему присваивается кодовая позиция — номер от 0 до 1 114 111 (или от 0 до 10FFFF в шестнадцатеричной системе). А за биты и байты отвечают форматы передачи: UTF-8, Punycode и другие. Вы и сами, если умеете программировать, можете придумать свой формат передачи Юникода.

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

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Заблуждение: Ну что такое, в новом Юникоде теперь крупные эмодзи.

Реальность: Насколько крупно рисовать — это дело прикладного ПО. Задача Юникода — сделать, чтобы все эплы, гуглы и фейсбуки кодировали сходные картинки одинаковыми цифрами.

И даже был курьёзный случай: существовал эмодзи 1F92D — колобок с улыбающимися глазами и ртом, закрытым рукой. Ну явно сдерживает смех. Но Эпл и Фейсбук рисовали глаза широко открытыми — неописуемый ужас. Их разунифицировали, эпловская версия получила номер 1FAE2.

И ещё — Юникод никогда не закодирует конкретную картинку — какого-нибудь преведа или догэ. Юникод кодирует идею, а художник может нарисовать эту идею по-разному.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Односимвольные эмодзи

Пример: ехидный колобок состоит из одного символа 1F600.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

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

VS16-эмодзи

Пример: красное сердце 2764+FE0F

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Такой механизм применяется в основном для старых символов, существовавших до 2010 года, а также принятых в эмодзи с опозданием (напоминаю, принимали их по несколько сотен за раз). Чтобы отобразить символ графикой, за ним ставится невидимая метка «селектор начертания 16» (variation selector 16) FE0F.

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

Совет: если в таблице символов видите эмодзи, а копипаста, например, в браузер упорно выводит символ текстом — вероятно, не хватает того самого VS16. Или найдите другую таблицу, или скопируйте-вставьте символ FE0F отдельно.

Существует и обратный селектор — FE0E, делающий из эмодзи текст. Вот вам футбольный мяч+FE0E: ⚽︎

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

Цвета кожи

Пример: негритянская рука OK 1F44C+1F3FF

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Как видите, цвет кожи — это просто символ-метка. Система, если может, собирает из руки и тёмной кожи тёмную руку. А если не может — будет просто рука и чёрный лоскут.

Флаги государств

Есть специальный алфавит, и флаг — это две буквы из этого алфавита. В Windows 10 во всех «хромых» браузерах будет «GB», а Firefox содержит флаги государств и всё-таки нарисует «юнион джек».

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

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

ZWJ-последовательности

Пример: белый бесполый врач 1F9D1+1F3FB+200D+2695+FE0F

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Посмотрим, как эта штука устроена. Первые два символа — это эмодзи «белый человек». Последние два — посох Асклепия. А между ними — невидимый символ «нулевой соединитель» (zero width joiner) 200D. Даже если система не может собрать из них врача, будет как-то понятно.

Другой вариант — картинка деятельности + ZWJ + символ пола.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

А также:

  • ворона = 🐦 + ZWJ + ⬛

  • свежачок Юникода 15.1 (выйдет в сентябре): человек, идущий вправо = 🚶‍♂️ + ZWJ + ➡️ + VS16

Ну и рекордсмен Юникода — межрасовый поцелуй. Целых десять символов: четыре эмодзи, соединённые тремя ZWJ.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Из-за такого устройства у ZWJ-последовательностей есть и второй путь кодирования: производитель придумывает последовательность, вписывающуюся в правила, и если она станет популярной, Консорциум её внесёт в Юникод.

Инклюзивность

Примерно с 2018 начали заботиться об инклюзивности. У каждого эмодзи есть бесполая, мужская и женская версия, исключения три:

  • женщина в хиджабе (мусульманском платке) 🧕;

  • женщина, кормящая грудью 🤱;

  • танцор 💃 — изначально это была женщина в латиноамериканском платье. Потом добавили мужчину в костюме диско 🕺. А вот что будет танцевать бесполая версия — так и не определились (пока склоняются к брейку или контемпу).

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

Забавная история. В шрифте Webdings в позиции 6D находится стилизованный восклицательный знак — мужчина в очках и деловом костюме левитирует. В 2014 году закодировали Wingdings и Webdings, превратив часть картинок в эмодзи — этот левитирующий (1F574), по стандарту, бесполый и может иметь расу.

Когда на картинке двое или более людей, в Юникоде существуют четыре способа раздать им расы:

  • Собрать через ZWJ из меньших эмодзи. Таких сборок всего четыре: поцелуй (см. выше), рукопожатие, любовь, пара людей. Согласитесь, важные!

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

  • Забить на расы из-за комбинаторного взрыва: все семьи без расы, иначе было бы много-много тысяч картинок.

  • Забить на расы из-за маловажности: борцы и танцоры Плейбоя есть всех трёх полов, но без расы.

Как устроены эмодзи Эмодзи, Unicode, Кодировка, Длиннопост

Колобки не инклюзивны, они всегда лысые и жёлтые.

У меня есть идея эмодзи. Как предложить?

Консорциум Юникода всегда (а вот и нет, каждый год в апреле-мае) готов выслушать ваши предложения. До настоящих эмодзиков доходят не более четверти заявок. За год выходит 20…30 штук.

Чего они точно НЕ примут:

  • связанные с текущими событиями: тонущий корабль, коронавирус (Эпл перерисовал 🦠 1F9A0 «микроорганизм»)

  • конкретные картинки и объекты: догэ, Сталин, Христос, Эйфелева башня. Принять могут только военного: собака 🐕 есть, а телебашни хватит токийской 🗼

  • надписи, флаги

  • слишком специфичные: F-35, пицца с колбасой. Принять могут только военный самолёт, пиццу и колбасу

  • изобразимые текущими картинками: мытьё рук, ведь есть руки 👐 и мыло 🧼

  • вызывающие каскадное добавление новых эмодзи: ленточки, символизирующие различные заболевания

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

Я пишу программу «Юникодия» — энциклопедию символов Юникода. Качать тут.

Показать полностью 13

Ответ на пост «Двери, как важная часть игры»

Лиз Инглэнд. Дверной вопрос в геймдизайне (перевод с сайта «Посмотрели», большей частью мой)


«Так что ты, геймдизайнер, делаешь? Ты рисуешь персонажей, пишешь сюжет? Или, постой, ты программист?»


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


Дверной вопрос


Мне нравится объяснять свою работу в терминах «дверного вопроса». Дано: вы делаете игру.

• Будут ли там двери?

• Может ли игрок их открывать?

• Может ли человек открыть любую дверь, или там будут двери для красоты?

• Как мы объясним разницу? Может, открывающиеся будут зелёными, а вечно закрытые — красными? Или неоткрывающиеся будут завалены мусором? А может, просто уберём с неоткрывающихся ручки, и всё?

• Можно ли двери запирать и отпирать?

• Что говорит о том, что дверь заперта, но когда-нибудь откроется — в отличие от двери, которая не откроется никогда?

• Знает ли игрок, как открыть дверь? Нужен ключ? Нужно взломать пульт? Нужно решить головоломку? Дождаться какого-то сюжетного момента?

• Есть ли двери, которые можно открыть, но нельзя войти?

• Откуда появляются враги? Из дверей? Запираются ли двери после этого?

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

• Закрывается ли дверь за спиной игрока?

• Что будет, если в игре двое? Нужно ли запирать дверь, когда пройдут оба?

• А что, если уровень СОВСЕМ ГРОМАДНЫЙ и всё не умещается в памяти? Если один игрок отстанет, не исчезнет ли пол под ним?

• Нужно ли как-то приостанавливать прохождение первого, пока второй не войдёт в комнату?

• Нужно ли телепортировать отставшего?

• Какого размера дверь?

• Нужно ли ей быть достаточного размера, чтобы игрок прошёл?

• Когда один игрок встанет в проёме, помешает ли это второму?

• А что, если за вами идут компьютерные союзники? Сколько их должно проходить сквозь дверь без застреваний?

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


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


Другие дверные вопросы


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

Творческий директор: Да, нам нужны двери.

Менеджер по проекту: Я отведу в графике время на двери.

Геймдизайнер: Я написал документ, уточняющий, что нам нужно от дверей.

Концепт-художник: Я нарисовал роскошные образцы дверей.

Арт-директор: На третьей картинке именно та дверь, которая нам нужна.

3D-моделер: По картинке я смоделировал дверь.

Аниматор: Я сделал, чтобы дверь открывалась и закрывалась.

Шумовик: Я сделал звуки открытия-закрытия дверей.

Специалист по звуковой подсистеме: Звуки будут меняться в зависимости от того, где игрок и в какую сторону он будет смотреть.

Композитор: Я сделал музыку для дверей.

Художник по эффектам: Я добавил искорки, когда дверь открывается.

Писатель: Когда дверь открывается, игрок скажет: «Смотрите, дверь открылась!»

Осветитель: Когда дверь заперта, она будет подсвечена красным, когда открыта — зелёным.

Юрист: 3D-моделер нарисовал на двери эмблему «Макдональдса». Её придётся убрать, чтобы не засудили.

Художник по персонажам: Меня дверь не волнует, пока она не будет носить шляпы.

Геймплейный программист: Дверь открывается и закрывается в зависимости от расстояния до игрока. Также её можно отпереть-запереть скриптом.

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

Программист сетевого кода: Нужно ли, чтобы все одновременно видели дверь открытой или закрытой?

Инженер по выпуску: Чтобы дверь попала на золото, её нужно закончить к 15:00.

Программист движка: Я оптимизировал код, и теперь может быть до 1024 дверей.

Программист-утилитчик: Я переделал редактор, теперь ставить двери проще.

Конструктор уровней: Я поставил запертую дверь. После события она откроется.

Дизайнер интерфейса: Теперь на самóй двери и на карте есть значок цели.

Постановщик боёв: Враги появляются за дверью; часть входит в комнату, часть остаются прикрывать огнём. Если игрок смотрит за дверь, они появятся за другой дверью.

Дизайнер систем: Игрок 4-го уровня тратит 3 золота и получает 148 опыта за открывание двери.

Специалист по монетизации: С игрока берём 99¢, чтобы он вошёл в дверь. После 24 часов ожидания — бесплатно.

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

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

Переводчик: Дверь. Door. Puerta. Porta. Porte. Tür. Dør. Deur. Drzwi. Drws. 문

Продюсер: Мы дадим эту дверь всем или оставим как бонус за предзаказ?

Издатель: Эта дверь выделит игру из линейки аналогичных, вышедших этой осенью.

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

Пиарщик: Всем поклонникам, вы сойдёте с ума от нашего нового пресс-релиза #геймдев #двери #некстген #ретвит

Менеджер по сообществу: Всем поклонникам, проблемы с дверью решим в следующем патче.

Техподдержка: Писал игрок, непонятки с дверями. Сбросил ему детальную инструкцию, как ими пользоваться.

Игрок: А дверь-то я и не приметил!


Одна из причин, за что я люблю этот пример — он такой обыденный. Часто думают, что разработка игр — это блестяще и круто, и буйство фантазии, и всегда интересно. Но когда я говорю: «Давайте начнём с дверей»,— всё сдувается до повседневных практических вопросов.


Комментарии пользователей(всё вперемешку, и с Гамасутры, и из блога Лиз)


Аниматор: Я сделал, чтобы дверь открывалась и закрывалась.

Менеджер проекта: Ты сделал анимацию, чтобы персонаж открывал дверь, или это дверь как в «Звёздном пути»?

Программист: Когда игрок сдаёт назад, что будет, если сзади кто-то окажется?

Программист физики: Сталкиваются ли двери с рэгдоллами? Может ли рэгдолл заблокировать дверь?

Программист, занимающийся камерой: Должна ли камера проходить сквозь дверь? Нужно ли ей особое поведение вокруг дверей?

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

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

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

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

Художник по персонажам: Надо сделать дверь повыше, не все персонажи умещаются.

Техподдержка: У нас проблемы с людьми, которые открывают-закрывают двери и не дают другим входить.

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

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

Пользователь Steam: Вы просите x$ на игру о дверях? Простите, я пас. Если бы вы просили вдвое меньше, вы продали бы стопятьсот триллионов копий.

Разработчик на Kickstarter: Сейчас у нас 20 дверей. Если мы соберём 150000 $, мы добавим ещё десять за то, что вы помогли нашей разработке!

Бизнес-исследователь: Средний игрок открывает 23 двери в час.

Безопасник: Боты с лёгкостью могут эксплуатировать двери.

Инженер по масштабируемости: Когда 1 млн человек одновременно закроют двери, игра «упадёт».

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

Веб-дизайнер: Я написал руководство по всем дверям в игре.

SEOшник: Дверь, портал, проход, вход, выход, арка, ворота, калитка, люк.

Специалист по продажам: Для BestBuy нужны синие двери, для Target — красные.

Историк: Дверной молоток появился только через 200 лет после событий в игре.

Технический художник 1: Я сделал модульный риг, который можно присоединить к любой двери в игре.

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

Технический художник 3: Я написал утилиту для Maya, которая за 30 секунд генерирует 1000 разных дверных сеток.

Технический художник 4: Я написал убер-шейдер, который прибавляет прозрачность, когда игрок приближается, превращает дверь в голограмму и анимирует UV, чтобы был эффект ряби.

Технический художник 5: Я переписал соглашения по именованию. Теперь двери находятся в Environments/Props/Doors и называются «[префикс_мира]_prop_door_[размер_двери]_[open_или_closed]_mesh.[filetype]».

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

Внештатный историк: Дверь Второй мировой войны так не выглядит. Пластмассу тогда ещё не изобрели.

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

Тестер по локализации: Увеличьте дверь на 1 уровне, надпись «Выход» часто вдвое длиннее, чем в английском — например, по-фински «poistua».

Заказчик «серьёзной игры»: Если вы сделаете одну дверь бесплатно, мы заработаем с ней больше денег!

Специалист по вирусной рекламе: Можете снять FRAPS’ом открывающуюся дверь, чтобы я выложил на YouTube?

Юрист Apple: Мы подаём в суд за нарушение патента «Движущееся бинарное многообразие в трёхмерном пространстве».

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

Амбициозный инди-единоличник (реальная цитата из проекта, прошедшего Greenlight и канувшего в Лету): Пре-альфа 0.4 вышла. У меня не было времени как следует реализовать создаваемые пользователем воксельные двери переменного размера с проводкой, механикой и хакерством, это будет в следующем выпуске.

Художник комикса: Всё не так! В моём комиксе дверь была ярко-красной! Потому он и называется «Красная-красная дверь».

Стажёр по 3D: Не понимаю. Почему на двери не может быть 10 000 треугольников?

Игрок-дальтоник: Я не могу различить, открыта ли дверь, спасибо тебе, осветитель!

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

Спидраннер 1: Если дверь меня будет дамажить, у меня будут прибавляться хп. Это одна конкретная дверь, у которой перепутали показатель урона и сделали его отрицательным.

Спидраннер 2: Если смотреть на крайнюю правую искорку, высекаемую дверью при закрытии, и по звуку скрипа на втором лязге подпрыгнуть, стоя на стыке текстур порога двери и пола, то дверь выпихнет за пределы уровня… изи ран

Главный босс: Мы запаздываем на 6 месяцев. Вот дверь!

Показать полностью

Ответ на пост «Точность - вежливость королей!»

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

Глюки целых чисел

Минимальная единица компьютерной информации — бит. Это одна цифра двоичной системы счисления: 0 или 1.

Процессор одним махом работает не с одним битом, а с 8-ю. Или 16-ю. Или 32-мя. Или 64-мя — так называемая разрядность процессора, или длина машинного слова. Если вы такие олдфаги, что вспоминаете 8- и 16-битные приставки — всё верно, это разрядность их процессоров.

Ответ на пост «Точность - вежливость королей!» Перфекционизм, Точность, Интернет-магазин, Юмор, Скриншот, Ответ на пост, Длиннопост

8 битов — это байт. Позволяет записать числа от 0 до 2⁸−1, то есть от 0 до 255. Удобная цифра: позволяет записать 26·2=52 буквы английского алфавита, 33·2=66 букв русского, и на цифры со спецсимволами хватит.

При этом компьютер работает так: 254+1=255, а 255+1=0. Такой механизм сложения позволяет теми же операциями «сложить» и «вычесть» работать и с отрицательными числами в таком виде: 255=−1, 254=−2, и т.д. до 128=−128 (а также с числами во много-много машинных слов). Какое число хранится в памяти — со знаком или нет — компьютер никак не запоминает, это работа программиста и компилятора (программы, которая переводит исходный текст на языке программирования в машинный код).

Пример. В первой версии компьютерной игры Civilization у всех правителей был такой параметр, как воинственность. У всяких там Сталиных с Монтезумами она была 9 или 10, а у махатмы Ганди 1. При открытии демократии воинственность (которая записывалась однобайтовым числом без знака) падает на 2. В такой вот арифметике 1−2=255. Таким образом, в конце игры благовидный старичок начинал громить всех ядерными бомбами. «Сумасшедший Ганди» так полюбился публике, что в том или ином виде существовал во всех последующих «цивилизациях» — например, слетал с катушек, если его втянут в войну.

Ответ на пост «Точность - вежливость королей!» Перфекционизм, Точность, Интернет-магазин, Юмор, Скриншот, Ответ на пост, Длиннопост

Пример 2. В первых версиях игры UFO: Enemy Unknown приходилось выгонять бывалых солдат, потому что… сила превышала 255, превращалась в 0, и боец становился немощным.

Ответ на пост «Точность - вежливость королей!» Перфекционизм, Точность, Интернет-магазин, Юмор, Скриншот, Ответ на пост, Длиннопост

Запишем эти цифры и для других форматов компьютерных целых. И не говорите, что не встречали их в каких-то компьютерных глюках!

Ответ на пост «Точность - вежливость королей!» Перфекционизм, Точность, Интернет-магазин, Юмор, Скриншот, Ответ на пост, Длиннопост

Эти цифры могли получиться тремя методами.

• В результате арифметического переполнения без проверки границ. Я уже говорил, что для одного байта 0−1=255. А если байтов четыре (что в наши дни встречается чаще всего) — получится 0−1=4,2 млрд.

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

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

Глюки дат

Если даты нет, вы часто видите дату 1 января 1970 года или 30/31 декабря 1899 года. Та и другая — ноль в двух разных системах отсчёта.

Время операционной системы Unix отсчитывается в секундах, при этом нулём считается 1 января 1970 года. Добавляем к ним те самые 2,1 млрд секунд — и получим 18 января 2038 года, когда на 32-битных машинах время Unix уйдёт в минус.

В электронной таблице Lotus 1-2-3 даты считаются количеством дней, прошедших с 31 декабря 1899 года, с ошибкой, что 1900 год високосный (на самом деле нет!) Этот формат перебрался в электронную таблицу Excel и систему программирования Delphi, причём глюк 1900 года они разрешили по-разному: Excel заявил, что 1900 год у него так и будет високосным, а Delphi начал отсчёт с 30 декабря 1899 года.

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

Ответ на пост «Точность - вежливость королей!» Перфекционизм, Точность, Интернет-магазин, Юмор, Скриншот, Ответ на пост, Длиннопост

Откуда взялась проблема 2000, я толком и не знаю, и видел её лишь однажды: в том же Lotus 1-2-3 вместо 2000 года писался 19100, причём не везде, а выборочно. Смею предположить, что в каких-то очень старых машинах две цифры года записывались двоично-десятичным кодом и потому при переходе через столетие сбрасывались в 00. (Двоично-десятичный формат действительно широко используется в устройствах без микропроцессоров, чтобы упростить вывод на индикацию.)

Глюки дробных чисел

Форматы компьютерных дробных писались для удобства вычислителей (это люди, занимающиеся организацией вычислений на компьютере) и совершенно непригодны для хранения денежных сумм до копейки. (Уважающие себя бухгалтерские программы записывают денежные суммы в специальных форматах без потерь, простейший — 12 р. 34 коп. = 1234 коп.)

Из школы мы знаем, что любое число, кроме нуля, можно записать в стандартном виде: 162=1,62·10². Компьютерные дробные — это такой же стандартный вид, только в двоичной системе счисления: 5=1,01₂·2². (1,01 в двоичной — это наши 1,25.)

Кто помнит из школы, какие обыкновенные дроби представимы в виде конечной десятичной? Ответ: знаменатель должен иметь множителями только 2 и 5. А в виде двоичной дроби — знаменатель должен быть степенью двойки. Таким образом, самые простые числа вроде 0,1 представимы в виде компьютерных дробных только приблизительно.

Отсюда 0,1+0,2≠0,3. И выглядит это примерно так: 0,1≈26/256=1,1010₂·2⁻⁴, 0,2≈26/128=1,1010₂·2⁻³ — а 0,1+0,2=1,00111₂·2⁻² — округлив, получим 1,0100₂·2⁻²=20/64, в то время как 0,3≈19/64. Компьютеры, правда, поточнее будут и для 0,1 знаменатель 65 млн или даже больше — но принцип поняли.

Хорошие функции преобразования дробного в строку это учитывают и не пишут лишних цифр, но иногда проскакивает.

Ответ на пост «Точность - вежливость королей!» Перфекционизм, Точность, Интернет-магазин, Юмор, Скриншот, Ответ на пост, Длиннопост

А ещё среди компьютерных дробных есть два специальных числа: Inf («машинная бесконечность») и NaN («не число»). Их получить проще простого: Inf=1/0, NaN=0/0 (если делить их как дробные числа; на целый ноль делить нельзя). Они также широко используются в качестве особых значений («нет данных», «не найдено», «не установлено»).

Показать полностью 6
Отличная работа, все прочитано!