Обновить
2003
205

Переводчик-фрилансер

Отправить сообщение

L в аббревиатуре LLM означает «ложь»

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели12K

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

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

Поэтому позвольте мне сказать фразу, которая повергнет бывалого резидента Кремниевой долины в больший шок, чем дефекация на Маркет-стрит: не использовать ИИ совершенно нормально.

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

Читать далее

Умные таблетки будущего смогут точечно доставлять лекарства и брать образцы тканей

Уровень сложностиПростой
Время на прочтение13 мин
Охват и читатели5.3K

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

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

Мечта об универсальной таблетке стала причиной исследований в сфере проглатываемой электроники: маленьких капсул, предназначенных для мониторинга и даже лечения болезней изнутри желудочно-кишечного тракта (ЖКТ). Ставки высоки: заболевания ЖКТ осложняют жизнь десяткам миллионов людей по всему миру; среди них такие болезни, как воспалительные заболевания кишечника, целиакия и синдром избыточного бактериального роста. Для их диагностики пациентам часто приходится проходить запутанный лабиринт из анализов крови, томографии и инвазивной эндоскопии. В то же время, способы лечения могут привносить серьёзные побочные эффекты, потому что лекарства действуют на всё тело, а не только на проблемные участки.

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

Читать далее

Структуры данных на практике. Глава 6: Стеки и очереди

Время на прочтение9 мин
Охват и читатели5.8K

«Простота — требование, необходимое для обеспечения надёжности», — Эдсгер Дейкстра

Невидимая структура данных

В каждой программе используется стек — стек вызовов. Каждый вызов функции записывает в стек кадр, каждый возврат извлекает его. Он настолько фундаментален, что мы редко о нём задумываемся.

Но когда нам нужен собственный стек или очередь, крайне важно правильно выбрать реализацию.

Однажды я отлаживал вылет прошивки во встраиваемой системе RISC-V. У системы был планировщик задач, использующий очередь для управления ожидающими задачами. При большой нагрузке система вылетала с переполнением стека.

Переполнение стека? Очередь должна была находиться в куче, а не в стеке.

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

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

Читать далее

Мир снов, сгенерированный компьютером: виртуальная реальность для процессора 286

Время на прочтение12 мин
Охват и читатели12K

«Что есть "реальность"? И как определить её? Весь набор ощущений: зрительных, осязательных, обонятельных — это сигналы рецепторов, электрические импульсы, воспринятые мозгом.» — Морфеус, фильм «Матрица»

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

Моим первым компьютером был 286 с 1 МБ ОЗУ и жёстким диском на 50 МБ (если я правильно помню). Поэтому я решил взять процессор 286 и попробовать симулировать остальную часть компьютера вокруг него. Или хотя бы сделать так, чтобы он мог запускаться и выполнять какой-то простой ассемблерный код.

Два года назад я купил два процессора Harris 80C286-12. Мои воспоминания довольно туманны, но кажется, буква C в их маркировке важна, потому что она означает меньшую чувствительность к точности таймера (12 в конце означает, что процессор предпочитает работать на 12 МГц), и что на нём даже допустимо пошаговое выполнение.

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

Читать далее

Джими Хендрикс был системным инженером

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели17K

3 февраля 1967 года навсегда вошло в анналы истории музыки. В этот день Джими Хендрикс пришёл в лондонскую Olympic Studios для записи песни с использованием нового компонента. Эта песня — Purple Haze, а компонент — гитарная педаль Octavia, специально изготовленная для Хендрикса звукоинженером Роджером Майером. Педаль стала ключевым элементом сложной цепочки аналоговых элементов, формирующих окончательный звук, включая акустику самой студии. Звук записи был настолько новым, что когда они отправляли плёнки для ремастеринга в США, то приложили к ним письмо с объяснением, что дисторшн в конце — это не сбой, а намеренный эффект. Спустя несколько месяцев Хендрикс провёл своё легендарное электрогитарное выступление на Monterey International Pop Festival.

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

Читать далее

Как за сутки обойти миллиард веб-страниц

Уровень сложностиПростой
Время на прочтение13 мин
Охват и читатели7.7K

TL;DR:

1,005 миллиарда веб-страниц

25,5 часа

$462

По какой-то причине уже долгое время никто не писал о том, что требуется для краулинга большой части веба: последним обнаруженным мной источником был пост Майкла Нильсена за 2012 год[1].

Очевидно, что за это время много изменилось. Всё стало больше, лучше и быстрее: у CPU появилось намного больше ядер, на смену жёстким дискам пришли твердотельные накопители NVMe, скорости ввода-вывода которых сравнимы со скоростями RAM, существенно выросла ширина сетевых каналов, существенно расширился список типов инстансов EC2 и так далее. Но в чём-то ситуация и усложнилась: гораздо бóльшая часть веба стала динамической, а контент теперь более тяжёлый. Как поменялось состояние Интернета? Теперь узкие места стали другими, и для создания своего Google по-прежнему нужно около 41 тысячи долларов? Мне захотелось это узнать, поэтому я собрал и выпустил собственный веб-краулер1 в условиях похожих ограничений.

Читать далее

Одна строка кода, которая заблокировала 102 потока

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели18K

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

Это история о том, как DatatypeFactory.newInstance() поставил на колени наш высокопроизводительный Java-сервис, и об удивительно простом решении, позволившем полностью избавиться от проблемы.

Читать далее

3D-шейдер реального времени на Game Boy Color

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели13K

Я написал игру для Game Boy Color, которая рендерит изображения в реальном времени. Игрок управляет источником света и вращает объект.

Поиграть в неё можно здесь: https://blog.otterstack.com/posts/202512-gbshader/data/teapot.html

Посмотреть код и скачать ROM можно здесь: https://github.com/nukep/gbshader

Читать далее

Структуры данных на практике. Глава 5: Связанные списки — убийцы кэша

Уровень сложностиПростой
Время на прочтение9 мин
Охват и читатели12K

«Связанные списки — это goto структур данных.», — авторство приписывают разным системным программистам.

История из учебника

Все студенты, изучающие computer science, узнают о связанных списках на первом курсе по структурам данных. Их описание звучит привлекательно:

Преимущества (согласно учебникам):

- Вставки и удаления за O(1) в известных позициях

- Динамический размер: увеличиваются и уменьшаются согласно необходимости

- Пространство не тратится впустую: можно распределять ровно столько, сколько нужно

- Гибкость: простота реализации стеков, очередей и других структур

Недостатки (согласно учебникам):

- Поиск за O(n): необходим обход, начиная с головы списка

- Лишняя память: указатели добавляют оверхед

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

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

Вроде бы звучит разумно?

Проверка реальностью

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

Не потому, что ошибочен анализ «О» большого, в нём всё правильно, а потому, что он неполон. Он забывает про оборудование.

Читать далее

На что кодинг-агенты тратят наши токены

Время на прочтение10 мин
Охват и читатели17K

На прошлой неделе я попросил Claude устранить однострочный баг. Ему понадобилось 23 тысячи токенов. Потом тот же баг я попросил устранить Gemini. Он потратил 350 тысяч токенов. Да уж, на такое невозможно закрывать глаза.

Поэтому я написал Context Lens — трассировщик контекста, перехватывающий вызовы LLM API, чтобы показать, что же на самом деле находится в окне контекста с разбивкой по этапам. Я подключил его к четырём инструментам кодинга и дал им одну и ту же задачу. Результаты оказались настолько разными, что я решил написать об этом статью.

Вопрос

При работе с этими моделями мы платим за токены. Токены — это довольно сложная тема. По сути, это блоки информации; 1 токен приблизительно равен 4 символам английского текста. Чем больше токенов передаётся в модель, тем больше мы платим.

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

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

Читать далее

Автоматическая модернизация кода на Go при помощи go fix

Время на прочтение15 мин
Охват и читатели8.9K

В релизе 1.26 языка Go, выпущенном в этом месяце, есть полностью переписанная подкоманда go fix. Go fix использует набор алгоритмов для обнаружения возможностей улучшения кода; часто для этого применяются более новые фичи языка или библиотеки. В этом посте мы сначала покажем, как использовать go fix для модернизации кодовой базы на Go. Во второй части статьи мы расскажем о лежащей в основе этой подкоманды инфраструктуре и её эволюции. В третьей части мы познакомим вас с тематикой инструментов анализа с «самообслуживанием», которые помогают мейнтейнерам модулей и организациям кодироовать собственные правила и рекомендации.

Читать далее

Как Майкл Абраш удвоил скорость Quake

Уровень сложностиПростой
Время на прочтение14 мин
Охват и читатели20K

Вместе с релизом в 1999 году исходного кода Quake был выпущен файл readme.txt, написанный Джоном Кармаком. Особый интерес в нём вызвало одно предложение:

Также для сборки файлов на языке ассемблера требуется Masm. Можно изменить #define и выполнять сборку только с кодом на C, но версии с программным рендерингом при этом потеряют почти половину скорости.

Quake был вдвое быстрее благодаря написанному вручную ассемблерному коду? Давайте разберёмся, так ли это, как это работает, и какими были самые важные оптимизации.

Читать далее

Структуры данных на практике. Глава 4: Массивы и локальность кэша

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели8.4K

«Массив — самая важная структура данных в computer science», — Дональд Кнут (вольное изложение цитаты)

Простейшая структура данных

Массивы настолько просты, что мы иногда воспринимаем их, как нечто само собой разумеющееся. Смежная память, доступ за O(1): что тут ещё оптимизировать?

Всё.

Я работал над конвейером обработки пакетов сетевого коммутатора. Код был простым: считываем пакеты из кольцевого буфера (массива), обрабатываем их и записываем результаты в другой массив. Всё просто, правда?

Но производительность была ужасной. Мы обрабатывали 100 тысяч пакетов в секунду, хотя оборудование должно было справляться с 1 миллионом.

Профилировщик показал нечто странное:

$ perf stat -e cache-misses,instructions ./packet_processor

Performance counter stats:

450,000 cache-misses

1,000,000 instructions

450000 промахов кэша на 1000000 команд? То есть промах происходил раз в 2-3 команды. При простых операциях с массивами это не имело никакого смысла.

Проблема заключалась не в самих массивах, а в том, как мы их использовали.

Читать далее

Компилируем Quake, как будто на дворе 1997 год

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели15K

Первые исполняемые файлы Quake (quake.exe и vquake.exe) программировали на HP 712-60 с NeXT и кросс-компилировали при помощи DJGPP, запущенного на DEC Alpha server 2100A. В июне 1996 года, после выпуска игры, id Software, озабоченная стагнацией NeXT, решила поменять стек разработки.

Сразу после выпуска Quake мы перешли на оборудование Intergraph с Windows NT.

- Джон Кармак[1]

Следующие версии Quake (winquake.exe, glquake.exe) и QuakeWorld (qwcl.exe и qwsv.exe) разработаны и скомпилированы в Windows NT с помощью Visual C++ 4.X.

В этой статье описываются этапы по воссозданию процесса сборки двоичных файлов Quake win32 в том виде, в котором он происходил в 1997 году.

Читать далее

Ковёр навахо в виде интегральной схемы: таймер 555

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели13K

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

Читать далее

Главная цель Continuous Integration — это провал

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели7.7K

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

Что такое Continuous Integration?

Разработка ПО следует по цикличному итеративному паттерну. Разработчики вносят изменения, коммитят их в систему управления версиями, развёртывают их для пользователей и повторяют этот процесс. Этап continuous integration (CI) расположен между коммитами и развёртыванием, это выполнение автоматизированных проверок каждого коммита. Если проверка проходит успешно, мы говорим «CI пройдена», после чего изменение развёртывается. Если проверка проваливается, мы говорим «CI не пройдена», и изменение не развёртывается.

Если вы опытный разработчик, то, возможно, думаете: «Ну это само собой!». Чтобы по-настоящему осознать предназначение CI, нужно посмотреть, что происходит с CI и без неё.

Читать далее

Самый тупой способ повышения производительности

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели13K

Введение

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

Читать далее

Взламываем 40-летний донгл защиты от копирования

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели18K

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

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

Это ПО было написано на языке программирования RPG (Report Program Generator), который старше Кобола (!); он использовался в компьютерах IBM среднего ценового диапазона наподобие System/3, System/32 и вплоть до AS/400. Похоже, позже RPG портировали в MS-DOS, поэтому те же программные инструменты, написанные на RPG, могут работать на персональных компьютерах. Так фирма и оказалась в этой ситуации.

Эта бухгалтерская фирма работала на компьютере с Windows 98 (да, в 2026 году) и запускала написанное на RPG ПО в консольном окне DOS. Оказалось, что для работы ПО требовалось подключить к параллельному порту компьютера специальный аппаратный донгл защиты от копирования! В те времена это было достаточно распространённой практикой, особенно у поставщиков «корпоративного» ПО, защищавшего свои очень важные™ программы от неавторизованного применения.

Читать далее

Я создал вдвое более быстрый лексер, но обнаружил, что узким местом был ввод-вывод

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели14K

Я создал лексер ассемблера ARM64 (ну, точнее, сгенерировал его из моего собственного генератора парсера, но пост не об этом), обрабатывающий код на Dart вдвое быстрее официального сканера. Этого результата я добился при помощи статистических методик надёжного измерения малых различий в производительности. Затем я провёл его бенчмарк на 104000 файлов и обнаружил, что узким местом был не мой лексер, а ввод-вывод. Это история о том, как я случайно узнал, почему pub.dev хранит пакеты в виде файлов tar.gz.

Читать далее

Структуры данных на практике. Глава 3: Бенчмаркинг и профилирование

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели6.1K

Проблема измерений

Узнав из Главы 2 об иерархии памяти, вы, возможно, захотите оптимизировать свой код. Но есть одна проблема: как понять, что оптимизация на самом деле сработала?

Этот урок дорого мне обошёлся.

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

Я запустил код. Мне показалось, что он быстрее. Я закоммитил изменения.

Неделю спустя коллега провёл бенчмарки и выяснил, что моя «оптимизация» замедлила код на 15%. Я оптимизировал не то, но у меня не было данных, чтобы подтвердить мои предположения.

Вывод: никогда не доверяйте своей интуиции, всегда проводите замеры.

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

Читать далее
1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность