Неожиданные результаты эксперимента с хранением большого количества числе в массиве в 64-битным Pharo Smalltalk, которые меня удивили.
Дизайн и реализация виртуальной машины CPython
Наиболее интересной частью каждого языка, компилируемого в байт‑код является виртуальная машина (также известная как интерпретатор байт‑кода), в которой происходит исполнение байт‑кода. Поскольку это наиболее важная часть реализации языка, она должна быть крайне производительной. Даже если вы не занимаетесь разработкой компиляторов, знание внутреннего устройства ее реализации может дать вам возможность найти новые способы оптимизации вашего кода, что может быть полезно в других областях вашей работы. А если вы занимаетесь разработкой компиляторов, вам всегда стоит исследовать реализации в других языках, чтобы найти для себя новые трюки и потенциально упущенные детали.
В этой статье мы обсудим формат инструкций байт‑кода CPython, а также реализацию цикла обработки байт‑кода в интерпретаторе, где он и исполняется.
Как я узнаю ежедневные новости с помощью матричного принтера
Уже давно я начинаю свой день с разблокировки телефона и пролистывания различных новостей и соцсетей, чтобы оставаться в курсе событий. Это не слишком хорошо отражается на моем душевном состоянии и я уже давно пытаюсь снизить время, проводимое перед экраном. Но я все еще хочу оставаться в курсе происходящего, особенно по утрам.
Недавно я приобрел ударный матричный принтер на Ebay и подумал, что это прекрасная возможность создать собственную сводку новостей, отпечатанную и готовую к прочтению. Это я и сделал!
Самые быстрые мьютексы
Cosmopolitan Libc хорошо известна своим «полиглотным жирным бинарным» хаком, который позволяем исполняемым файлам запускаться на шести операционных системах для AMD64/ARM64. Вас может удивить, что при этом она может быть лучше С‑библиотекой для вашего продакшена. Чтобы продемонстрировать это, давайте сравним библиотеку мьютексов Cosmo с другими платформами.
Мы напишем простой тест, который создает 30 потоков, увеличивающих одно и то же число 100 000 раз. Это поможет проверить, насколько хорошо реализация мьютексов справляется с задачей при интенсивном использовании.
Планируем потоки как Томас Джефферсон
Эта статья посвящена тому, как распределять задачи между конвейерами очередей, чтобы минимизировать общее время обработки, а также неожиданной связи между этим методом планирования и методом Томаса Джефферсона.
Небольшая хитрость для простого взаимодействия Rust и C++
На работе я переписываю запутанный C++ код на Rust.
Из‑за активного использования коллбеков (вздох), Rust иногда вызывает C++, а C++ иногда вызывает Rust. Все это благодаря тому, что оба языка предоставляют C API для функций, которые можно вызывать со стороны противоположного языка.
Это касается функций; но как быть с методами C++? Представляю вам небольшую хитрость, благодаря которой можно переписать, без головной боли, один метод C++ за раз. И, кстати, это работает независимо от языка, на который вы переписываете проект, это не обязательно должен быть Rust!
Трассировка OpenTelemetry в 200 строк кода
Разработчики часто воспринимают трассировку как нечто загадочное, и OpenTelemetry — не исключение. Она может казаться еще более сложной из‑за множества новых концепций, с которыми сталкиваешься в базовых примерах.
Ситуация усугубляется тем, что по мере создания стабильной и надежной библиотеки для трассировки сам код усложняется, чтобы учитывать редкие случаи, поддерживать работу в разных окружениях и оптимизировать производительность, минимизируя влияние на приложения. Это особенно заметно при использовании автоматической инструментации, которая может «волшебным образом» оборачивать или изменять код, который изначально для этого не предназначен.
Неудивительно, что многие разработчики воспринимают библиотеки трассировки как «черные ящики». Мы добавляем их в приложения, надеемся на лучшее и полагаемся на них в критические моменты, например, во время инцидентов ночью.
На самом деле, трассировка гораздо проще, чем кажется.
Обход SSH Keystroke Obfuscation
В OpenSSH версии 9.5 были добавлены меры предотвращения keystroke timing‑атаки за счет анализа трафика. Патч включал добавление обфускации таймингов нажатий клавиш в клиенте SSH. Согласно информации о релизе, эта функция «пытается скрыть тайминги между нажатиями за счет отправки трафика взаимодействия через фиксированные интервалы времени (по умолчанию — 20 мс), когда отправляется малое количество данных». Также отправляются фейковые chaff‑пакеты после последнего нажатия, что значительно усложняет анализ трафика, скрывая реальные нажатия среди потока искусственных пакетов. Эта функция может настраиваться с помощью опции ObscureKeystrokeTiming
в конфигурации SSH.
Я исследовал влияние использования анализа задержек между нажатиями клавиш для определения отправляемых внутри сессии SSH команд клиентом в рамках моей бакалаврской диссертации. В ходе этого я обнаружил способ обхода этого метода обфускации, работающий вплоть до текущего релиза. Я оповестил разработчиков 24 апреля и получил ответ от самого Дэмьена Миллера (разработчик, добавивший данный патч), но, к сожалению, дальнейшая переписка была проигнорирована. Отсюда и публикация данной статьи.
Оптимизация, которая невозможна в Rust
В этой статье я опишу, как я реализовывал German string и с какими трудностями столкнулся в Rust. В особенности я рассмотрю, как добавить общее владение для подобной структуры данных.
Дорогая, я уменьшил {fmt}: уменьшил размер до 14kB и избавился от рантайма C++
Библиотека форматирования {fmt} известна своим небольшим влиянием на размер бинарников. Чаще всего её код в несколько раз меньше по сравнению с такими библиотеками, как IOStreams, Boost Format или, что иронично, tinyformat.
Давайте разберем, как можно уменьшить размер бинарников еще больше!
Создание Git-коммита: The Hard Way
Мы постоянно используем высокоуровневые команды git, такие как git add
и git commit
. Однако также существует другая группа команд git, которые обрабатывают низкоуровневые операции.
В этой статье мы создадим git‑коммит, используя низкоуровневые операции, а не команду git commit
.
Буфер обмена веб-приложений и как он хранит различные данные
Если вы достаточно давно пользуетесь компьютером, вы, скорее всего, знаете, что буфер обмена может хранить различные данные (картинки, текст с форматированием, файлы и др.). Как разработчика, меня начало раздражать то, что у меня нет точного представления, как буфер обмена хранит и организует данные разных типов.
Недавно я решил разобраться в механике работы буфера обмена и написал этот пост на основе моих изысканий. В основном речь пойдет о буфере обмена и его API, но мы также поговорим о том, как он взаимодействует с системным буфером обмена.
Давайте начнем с исследования различных API и их истории. Эти API имеют весьма интересные ограничения по типам данных, и мы увидим, как некоторые компании обошли эти ограничения. Мы также рассмотрим некоторые предложения, которые направлены на устранение этих ограничений (наиболее примечательное из них — Web Custom Formats).
Если вам хотя бы раз было интересно, как работает веб-буфер обмена, то эта статья для вас.
Экстремальная оптимизация скорости загрузки Raspberry Pi
Некоторое время назад был создан проект SolarCamPi — автономная камера на солнечных батареях с Wi‑Fi.
В этом проекте Raspberry Pi Zero 2 W загружается в Linux, делает снимок, подключается к Wi‑Fi и затем выключается (для экономии энергии). Цикл повторяется каждые несколько минут, чтобы постоянно отправлять актуальные изображения в облачный сервис.
Каждая секунда работы Pi Zero, расходует ценную электроэнергию – ресурс, который постоянно находиться в дефиците у устройств на солнечных батареях (по крайней мере зимой в Западной Европе).
Давайте разберемся, каким образом можно уменьшить расход электроэнергии в такой ситуации.
Бэкдоры OpenSSH
Представьте себе: обнаружен бэкдор в OpenSSH, мейнтейнеры спешат выпустить релиз с исправлениями, исследователи безопасности обмениваются техническими деталями, чтобы проанализировать вредоносный код. Разгораются обсуждения по поводу причастности и мотивов злоумышленника, а технические СМИ бросаются освещать историю. Почти что эпическое происшествие, удар по доверию, лежащему в основе разработки с открытым исходным кодом, яркое напоминание о рисках атак на цепочки поставок. В равной мере блестяще и коварно.
Если вы следите за новостями безопасности, то, возможно, сразу вспомните атаку на репозиторий liblzma/xz‑utils в начале этого года, конечной целью которой был бэкдор в OpenSSH. Однако ниже мы обсудим не случай с xz‑utils, ведь мало кто помнит, что бэкдор в xz‑utils на самом деле второй широко известной попыткой внедрения бэкдора в OpenSSH. Впервые это произошло более 22 лет назад, в 2002 году. Эта статья рассказывает историю того бэкдора и тому, чему можно научиться из атаки, произошедшей более двух десятилетий назад.
Вызовы функций в Python по прежнему медленные? Анализ последних оптимизаций в CPython
Я наткнулся на пост в X/Twitter, где Pritam обнаружил, что его решение на Leetcode работало медленнее, когда он использовал встроенную функцию min, и производительность улучшилась, когда он реализовал min прямо в своем коде на Python.
Это правда, что вызовы функций могут быть затратными, и они, как известно, еще более затратны в интерпретируемых языках, таких как Python. Стандартная рекомендация — использовать встраивание функций, если они являются частью узкого места.
Автор на этом скриншоте использовал Python 2, который на данный момент уже стал древностью. За последние 10 лет Python 3 получил множество релизов, и последние версии были нацелены на улучшение производительности языка. Так действительно ли вызовы функций по‑прежнему так сильно влияют на производительность в Python?
В этой статье я собираюсь обсудить конкретные улучшения, внесенные в CPython, которые повышают производительность интерпретатора. Рассмотрим причины медленной работы в старых версиях и как нововведения помогают исправить ситуацию. Давайте погрузимся в детали.
Linux Pipes – медленные
Я пишу программу для сверхбыстрого кодирования/декодирования азбуки Морзе и использую pipe для передачи данных. При этом pipe работает очень медленно. Давайте разберемся почему.
Разработка под Neo Geo: Числа с фиксированной запятой
Давайте рассмотрим, как работать с десятичными числами на древнем процессоре с помощью чисел с фиксированной запятой.
Блокчейн за пределами мира криптовалют
Блокчейн, изначально разработанный для обеспечения безопасности и прозрачности в мире криптовалют, сегодня выходит за пределы этой узкой сферы и находит применение в самых различных областях. Начиная с управления цепочками поставок до улучшения систем здравоохранения и государственного управления – возможности технологии блокчейн значительно расширились.
В этой статье мы рассмотрим как блокчейн изменяет традиционные процессы в различных секторах, демонстрируя свои преимущества и потенциал для трансформации ключевых аспектов современного мира.
Как построена DDoS защита пользователей на хостинге. С какими атаками мы сталкиваемся и как с ними справляемся
Лето 2022 года по-настоящему жаркое, и речь не только о погоде: в последнее время в нас, как и в других хостеров, летят DDoS-атаки в сотни Гбит/c практически каждый день. Зачастую отбить атаку на свой личный сайт не составляет большого труда. Но что делать, если ты хостер и надо одновременно защищать сотни тысяч сайтов?
Сегодня мы хотим рассказать как раз об этом :)
Как я перестроил почти с нуля отдел техподдержки хостинга за 4 года
Мы довольно быстро выросли от маленького хостинга до одного из лидеров рынка (сейчас с нашего хостинга открывается 12,7% сайтов Рунета). В середине этого процесса стало понятно, что надо либо забить на количество пропущенных звонков, либо что-то принципиально менять в организации работы. Были все шансы стать стереотипной поддержкой с типичной отбивкой «попробуйте перезагрузить» в ответ на подробное описание проблемы, то есть бездушными бюрократами, которым важно выполнить скрипт, а не решить проблему.
Но сначала надо было решить другую задачу: в 2017 году мы не отвечали на примерно каждый десятый звонок. То есть человек звонил-звонил, ждал 10-12 гудков, потом клал трубку. И если он не перезванивал, надеялись, что человек справился сам.
Хотелось, чтобы звонки не терялись. И ответы были нормальные человеческие.