Обновить
64K+

Качество кода *

Как Макконнелл завещал

65,47
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Как реализованы конвейеры в Unix

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

В этой статье описана реализация конвейеров в ядре Unix. Я был несколько разочарован, что недавняя статья под названием «Как работают конвейеры в Unix?» оказалась не про внутреннее устройство. Мне стало интересно, и я зарылся в старые источники, чтобы найти ответ.
Читать дальше →

Zip-файлы: история, объяснение и реализация

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


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

В статье очень подробно объясняется, как работают Zip-файлы и схема сжатия: LZ77-сжатие, алгоритм Хаффмана, алгоритм Deflate и прочее. Вы узнаете историю развития технологии и посмотрите довольно эффективные примеры реализации, написанные с нуля на С. Исходный код лежит тут: hwzip-1.0.zip.
Читать дальше →

Монады как паттерн переиспользования кода

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


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


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


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


Дело в том, что все их (по крайней мере те что я читал) можно поделить условно на две категории: с одной стороны это статьи где вам объяснят что монада это моноид в категории эндофункторов, и что если монада T над неким топосом имеет правый сопряжённый, то категория T-алгебр над этой монадой — топос. На другой стороне располагаются статьи, где вам рассказывают, что монады — это коробки, в которых живут собачки, кошечки, и вот они из одних коробок перепрыгивают в другие, размножаются, исчезают… В итоге за горой аналогий понять что-то содержательное решительно невозможно.


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


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

Читать дальше →

Нет, динамические системы типов по своей сути не более открыты

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

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


Читать дальше →

Прощай, чистый код

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


Был поздний вечер.

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

Код работал.

Но в нём было много повторяющихся однотипных конструкций. Каждая фигура (вроде того же прямоугольника или овала) обладала различным набором маркеров. Перемещение этих маркеров в разных направлениях по-разному влияло на позицию и размер фигуры. А если пользователь, двигая маркеры, удерживал нажатой клавишу Shift, нам, кроме того, надо было сохранять пропорции фигуры при изменении её размера. В общем — в коде было много вычислений.
Читать дальше →

Публикация кода VVVVVV показала, насколько грубо устроены игры внутри

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

На прошлой неделе создатель Dicey Dungeons Терри Кавана отпраздновал десятую годовщину своей давней игры VVVVVV, by опубликовав её исходный код [перевод на Хабре]. Если объяснять просто, то это значит, что любой человек может теперь посмотреть, как создавалась игра, потому что каждую строку кода можно внимательно изучить.

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

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

Функциональное программирование — это не то, что нам рассказывают

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

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



Хотя люди обычно признают удобства ФП фич, ведь намного приятнее писать:


int Factorial(int n)
{
    Log.Info($"Computing factorial of {n}");
    return Enumerable.Range(1, n).Aggregate((x, y) => x * y);
}

чем ужасные императивные программы вроде


int Factorial(int n)
{
    int result = 1;
    for (int i = 2; i <= n; i++)
    {
        result *= i;
    }
    return result;
}

Так ведь? С одной стороны да. А с другой именно вторая программа в отличие от первой является функциональной.


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

Читать дальше →

LeanChess — самые маленькие компьютерные шахматы в мире

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

Меня зовут Дмитрий Шехтман, и я автор самых маленьких компьютерных шахмат в мире.


Началось всё с того, что моя (ныне бывшая) девушка предложила написать компьютерные шахматы. Идея меня заинтересовала, и я решил этим заняться. Правда, почитав интернет, я понял, что опоздал лет на сорок. Особенно впечатляли шахматные разработки Оскара Толедо — на Си размером в 1257 байт, на JavaScript в 1023 байта и, наконец, Atomchess на ассемблере x86, компилирующийся в 392 байта.


Прежде, чем я вернулся к теме, прошло несколько месяцев. Как оказалось, за это время был установлен новый рекорд размера — ChesSkelet для ZX Spectrum занимал всего 352 байта. Правда, он не знал всех правил и играл весьма слабо, но всё же! А не замахнуться ли мне на шахматы на ассемблере? — подумал я.

Читать дальше →

Как работает оптимизирующий компилятор

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

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

В этой статье мы рассмотрим некоторые из основных методик приведения (inference techniques) в оптимизирующих компиляторах: как спроектировать программу, с которой компилятору будет легко работать; какие приведения можно сделать в вашей программе и как использовать их для её уменьшения и ускорения.
Читать дальше →

Как проводить Code Review по версии Google

Время на прочтение5 мин
Охват и читатели145K
Вопросы код-ревью меня интересуют очень давно. Много раз возникали те или иные проблемы то с качеством кода, то с климатом в коллективе. И действительно, code review — это если не единственное, то одно из самых главных мест для возникновения конфликтов в коллективе разработчиков.

И вот недавно при подготовке к очередному выпуску подкаста "Цинковый прод" я узнаю, что Google опубликовал свод правил по проведению Code Review, битком набитый ценными мыслями. Весь материал довольно объемный и не влезет в одну статью, поэтому я постараюсь выделить наиболее интересные (мне) мысли.


Итак, поехали

Читать дальше →

Принцип открытости-закрытости

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

Привет, Хабр! Перед вами перевод статьи Роберта Мартина Open-Closed Principle, которую он опубликовал в январе 1996 года. Статья, мягко говоря, не самая свежая. Но в рунете статьи дяди Боба про SOLID пересказывают только в урезанном виде, поэтому я подумал, что полный перевод лишним не будет.



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


  • Ни одну программу нельзя «закрыть» на 100%.
  • Объектно-ориентированное программирование (ООП) оперирует не физическими объектами реального мира, а понятиями — например, понятием «упорядочивание».
Читать дальше →

Я в одиночку отрефакторил 15 тысяч строк легаси. Это были худшие две недели в жизни

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


Несколько месяцев назад я работал в аутстафе. Это не то место, где нужен энтузиазм и вера в великую цель проекта. Меня вместе с командой просто продавали заказчикам, а на митингах было важно, сколько тикетов я закрыл. Приступы перфекционизма — скорее вредная штука для такого места, но я ничего не мог с ними сделать. За один из них я знатно поплатился, попал в адский кранч и провел худшие две недели в моей жизни.
Читать дальше →

Сложность простоты

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


Как я писал в предисловии предыдущей статьи, я нахожусь в поисках языка, в котором я мог бы писать поменьше, а безопасности иметь побольше. Моим основным языком программирования всегда был C#, поэтому я решил попробовать два языка, симметрично отличающиеся от него по шкале сложности, про которые до этого момента приходилось только слышать, а вот писать не довелось: Haskell и Go. Один язык стал известен высказыванием "Avoid success at all costs"*, другой же, по моему скромному мнению, является полной его противоположенностью. В итоге, хотелось понять, что же окажется лучше: умышленная простота или умышленная строгость?


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

Читать дальше →

Ближайшие события

Чему я научился у ведущего программиста

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

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

Это одна из причин, по которой я начал вести дневник. Каждый день, попадая в интересные ситуации, я описывал их. И всё благодаря тому, что я сидел рядом с ведущим программистом. Я мог вблизи наблюдать за его работой, и видел, насколько она отличается от того, что сделал бы я. Мы много программировали вместе, что ещё больше облегчало мои наблюдения. Более того, в нашей команде не осуждается «подглядывание» за людьми, пишущими код. Когда мне казалось, что происходит что-то интересное, я поворачивался и смотрел. Благодаря постоянным вставаниям я всегда был в курсе происходящего.

Я год просидел рядом с ведущим программистом. Вот чему я научился.

Грязные хаки ассемблера 6502

Время на прочтение10 мин
Охват и читатели23K
В этой статье перечислены некоторые трюки, которые применяли участники моего маленького конкурса программирования Commodore 64. Правила конкурса были просты: создать исполняемый файл C64 (PRG), который рисует две линии, чтобы сформировать изображение ниже. Побеждал тот, чей файл меньше по размеру.


Конкурсные работы публиковались в открытых твитах и личными сообщениями, которые содержали только байты PRG-файла и хэш MD5.
Читать дальше →

Трюк с тригонометрией

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

Скорее всего, вам известны следующие соотношения еще со школы:


$\sin(\alpha + \beta) = \sin\alpha \times \cos\beta + \cos\alpha \times \sin\beta \\ \cos(\alpha + \beta) = \cos\alpha \times \cos\beta - \sin\alpha \times \sin\beta$


Когда вы в детстве впервые познакомились с этой формулой, скорее всего, вашим первым чувством была боль из-за того, что эту формулу надо запомнить. Это очень плохо, потому что на самом деле вам не нужно запоминать эту формулу — она сама выводится, когда вы поворачиваете треугольник на бумаге. На самом деле, я делаю то же самое, когда записываю эту формулу. Это толкование будет очевидным к середине этой статьи. Но сейчас, чтобы оставить все веселье на потом и отодвинуть момент, когда вы скажете "Эврика!", давайте подумаем, а зачем нам вообще задумываться об этой формуле.


Читать дальше →

Избегаем тригонометрии

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

Вступление


Мне кажется, что нам надо использовать меньше тригонометрии в компьютерной графике. Хорошее понимание проекций, отражений и векторных операций (как в истинном значении скалярного (dot) и векторного (cross) произведений векторов) обычно приходит с растущим чувством беспокойства при использовании тригонометрии. Точнее, я считаю, что тригонометрия хороша для ввода данных в алгоритм (для понятия углов это интуитивно понятный способ измерения ориентации), я чувствую, что что-то не так, когда вижу тригонометрию, находящуюся в глубинах какого-нибудь алгоритма 3D-рендеринга. На самом деле, я думаю, что где-то умирает котенок, когда туда закрадывается тригонометрия. И я не так беспокоюсь о скорости или точности, но с концептуальной элегантностью я считаю… Сейчас объясню.
Читать дальше →

Я нашёл отличного программиста по имени Стив Возняк

Время на прочтение2 мин
Охват и читатели40K
Давным-давно, когда компьютеры были большими, а бизнес скучным, произошло нечто неожиданное. Молодые хакеры нашли способ собрать персональные компьютеры на дешёвых микропроцессорах от телетайпов и светофоров. Одним из них был Стив Возняк. Эти ребята восприняли ограничения своих компьютеров как вызов, сели и заставили эти крошечные чипы делать удивительные вещи. Вот что публиковал Dr Dobb's Journal в августе 1976 года:



Это набор арифметических процедур на действительных числах. Микропроцессор (6502, такой же, как в Apple I и II) мог работать только с байтами, то есть целыми числами между 0 и 255. Хуже того, он мог только складывать и вычитать их. Но с помощью этой библиотеки вы можете вычислить $1.2627-1099.56$, или даже взять квадратный корень из пи. Удивительно, но автор программы по имени Стив Возняк уместил основные функции (сложение, вычитание, умножение и деление) в 239 байт, используя всего 127 инструкций.
Читать дальше →

Чему я научился на своём горьком опыте (за 30 лет в разработке ПО)

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

Это циничная, клиническая коллекция того, чему я научился за 30 лет работы в разработке программного обеспечения. Повторюсь, некоторые вещи весьма циничны, а остальное — результат долгих наблюдений на разных местах работы.
Читать дальше →

Стоит ли высокое качество ПО затрат на его разработку?

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

Часто в процессе реализации проектов команды сталкиваются с вопросом: чему следует уделять больше внимания – выпуску новых фич или повышению качества кода? Обычно менеджеры делают выбор в пользу фич. Зачастую разработчики таким положением дел недовольны, считая, что им выделяется недостаточно времени для работы над архитектурой и качеством кода.

Закон Беттериджа гласит: «На любой заголовок, который заканчивается вопросительным знаком, можно ответить словом нет». Те, кто знаком со мной лично, знают, что я не разделяю эту мысль. Но в этой статье я хочу пойти ещё дальше и доказать, что постановка вопроса из заголовка этой статьи просто не имеет смысла. Такая постановка вопроса предполагает, что существует компромисс между затратами и качеством. И необходимо постоянно соблюдать баланс. В этой статье я докажу, что к миру разработки компьютерных систем этот компромисс не применим и, в действительности, создавать ПО высокого качества оказывается в конечном счёте дешевле.

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