Search
Write a publication
Pull to refresh
35
0.9
Константин @Cerberuser

Разработчик, экспериментатор

Send message

Хабрарейтинг 2019: статистика и рейтинг авторов за 2019 год

Reading time7 min
Views13K
Привет Хабр.

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



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

Продолжение под катом.
Читать дальше →

Хабрарейтинг 2019: статистика и рейтинг лучших статей за 2019 год

Reading time8 min
Views10K
Привет, Хабр.

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



Парсинг и обработка данных были за этот год улучшены (кстати, изображение на КДПВ сгенерировано на базе заголовков статей), так что надеюсь, результаты будут более интересными. Также я добавил две новые категории в рейтинге — теперь отдельно будут рассматриваться хабы «ИТ-эмиграция» и «Здоровье», думаю, для многих и то и то может быть актуально.

Продолжение и результаты под катом.
Читать дальше →

Простое объяснение алгоритмов поиска пути и A*

Reading time13 min
Views74K
image

Часть 1. Общий алгоритм поиска


Введение


Поиск пути — это одна из тех тем, которые обычно представляют самые большие сложности для разработчиков игр. Особенно плохо люди понимают алгоритм A*, и многим кажется, что это какая-то непостижимая магия.

Цель данной статьи — объяснить поиск пути в целом и A* в частности очень понятным и доступным образом, положив таким образом конец распространённому заблуждению о том, что эта тема сложна. При правильном объяснении всё достаточно просто.

Учтите, что в статье мы будем рассматривать поиск пути для игр; в отличие от более академических статей, мы опустим такие алгоритмы поиска, как поиск в глубину (Depth-First) или поиск в ширину (Breadth-First). Вместо этого мы постараемся как можно быстрее дойти от нуля до A*.
Читать дальше →

'Hello World' вам в облако

Reading time69 min
Views25K

Мир сходит с ума, заталкивая калькулятор для 2+2 в облака. Чем мы хуже? Давайте Hello World затолкаем в три микросервиса, напишем пару-тройку тестов, обеспечим пользователей документацией, нарисуем красивый пайплайн сборки и обеспечим деплой в условный облачный прод при успешном прохождении тестов. Итак, в данной статье будет показан пример того, как может быть построен процесс разработки продукта от спецификации до деплоя в прод. Инетересно? тогда прошу под кат

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

Reading time17 min
Views129K

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



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


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;
}

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


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

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

Так все же, зачем нужен make?

Reading time3 min
Views24K


Все началось, казалось бы, с простого вопроса, который сначала ввел меня в ступор — "Зачем нужен make? Почему нельзя обойтись bash скриптами?". И я подумал — Действительно, зачем нужен make? (и самое важное) Какие проблемы он решает?

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

Размышления на тему ООП и состоянии объектов

Reading time9 min
Views5.7K

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


Однажды подобный код попался мне на глаза.

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

Dap — еще один реактивный движок для веба. Совсем другой

Reading time10 min
Views4.9K
Хочу рассказать про dap — интересный и необычный язык реактивных правил для написания, в частности, веб-фронтендов.

Для затравки простая задачка: взять список неких пользователей (воспользуемся тестовыми данными, любезно предоставляемыми сервисом jsonplaceholder.typicode.com) и вывести их имена обычным html-списком; при нажатии на имя пользователя — показать алерт с его id.

Это, конечно, легко делается и на React, и на Angular, и на Vue. Вопрос: насколько легко? В dap это делается так:

'UL.users'.d("* :query`https://jsonplaceholder.typicode.com/users"
 ,'LI'.d("! .name").ui("? .id:alert")
)

(*Этот и последующие dap-примеры можно интерактивно потестить в песочнице dap.js.org/test.html)

Это первая пришедшая в голову тривиальная задачка и тривиальный же способ ее решения. На dap удобно писать «в лоб», не городя огород из классов, компонентов и прочего ритуального реквизита. Что вижу, то пою. Но «пою» не на javascript или его производных, а на языке dap-правил, специально заточенном на простое и лаконичное описание реактивных зависимостей между элементами.
Читать дальше →

История Vim и руководство по его эффективному использованию

Reading time14 min
Views52K
Примечание от переводчика: это первая часть монументальной (на самом деле монументальной) статьи о Vim и его возможностях от разработчика из Миннеаполиса и автора проекта PostgREST Джо begriffs Нельсона.

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




Эта статья основана на исследовании истории Vim и прочтении его руководства пользователя от корки до корки. Надеюсь, эти заметки помогут вам открыть (или переоткрыть?) для себя основные функциональные возможности этого редактора, а также позволят отказаться от использования предупакованных файлов vimrc и более вдумчиво использовать плагины.



Список литературы


Чтобы выйти за границы привычных тем, я бы порекомендовал обзавестись бумажной копией этого руководства и емким карманным справочником. Я не смог найти печатную копию руководства пользователя для Vim, так что в итоге просто распечатал идущий вместе с редактором PDF-файл с помощью printme1.com. Он идет вместе с софтом в $VIMRUNTIME/doc/usr_??. В качестве удобного списка команд могу посоветовать справочник «Vi and Vim Editors Pocket».

Содержание

  • История
  • Иерархия конфигурации
  • Сторонние плагины
  • Бекапы и откаты
  • Include и path
  • Редактирование и компиляция цикла
  • Диффы и патчи
  • Буфер ввода / вывода
  • Типы файлов
  • Не забывайте про мышь
  • Разное

История


Рождение vi


Команды и функции Vi существуют уже более пятидесяти лет, начиная с редактора QED. Вот его таймлайн:
Читать дальше →

Rust для веб-разработчика — быстрый старт и стремительный полет

Reading time21 min
Views30K
Всем привет! Сегодня хочу поделиться опытом изучения языка и быстрой реализации высоконагруженного сетевого проекта, использующего так популярные и востребованные сейчас неблокирующие асинхронные сетевые соединения, на новом, красивом, элегантном и очень эффективном языке Rust.
Особый упор в посте сделаю на быстрое и ясное объяснение возможностей языка и платформы специалистам, имеющим большой опыт в веб-разработке, ибо сам таким и являюсь. Существует заблуждение, что кривая вхождения в Rust — очень-очень крутая. Но я покажу, что это далеко не так. Наливаем кофе и погнали!
Читать дальше →

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

Reading time23 min
Views19K

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

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

Как LLVM оптимизирует функцию

Reading time10 min
Views10K
Оптимизирующий AOT-компилятор обычно структурирован так:

  1. фронтенд, преобразующий исходный код в промежуточное представление
  2. конвейер машинно-независимой оптимизации (IR): последовательность проходов, которые переписывают IR для устранения неэффективных участков и структур, которые не могут быть непосредственно преобразованы в машинный код. Иногда эту часть называют middle-end.
  3. Машинно-зависимый бэкенд для генерации ассемблерного кода или машинного кода.



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

Самые позорные ошибки в моей карьере программиста (на текущий момент)

Reading time8 min
Views125K

Как говорится, если тебе не стыдно за свой старый код, значит, ты не растешь как программист — и я согласна с таким мнением. Я начала программировать для развлечения более 40 лет назад, а 30 лет назад и профессионально, так что ошибок у меня набралось очень много. Будучи профессором информатики, я учу своих студентов извлекать уроки из ошибок — своих, моих, чужих. Думаю, пришло время рассказать о моих ошибках, чтобы не растерять скромность. Надеюсь, кому-то они окажутся полезны.
Читать дальше →

Алгоритм Кэхэна: как получить точную разность произведений

Reading time5 min
Views9.8K
image

Недавно я вернулся к анализу погрешностей чисел с плавающей запятой, чтобы усовершенствовать некоторые детали в следующей редакции книги Physically Based Rendering. Числа с плавающей запятой — интересная область вычислений, полная сюрпризов (хороших и плохих), а также хитрых трюков, позволяющих избавиться от неприятных неожиданностей.

В процессе работы я наткнулся на этот пост на StackOverflow, из которого узнал об изящном алгоритме точного вычисления $a \times b-c \times d$.

Но прежде чем приступать к алгоритму, нужно понять, что же такого хитрого в выражении $a \times b-c \times d$? Возьмём $a=33962.035$, $b=-30438.8$, $c=41563.4$ и $d=-24871.969$. (Это реальные значения, которые получились у меня во время запуска pbrt.) При 32-битных значениях float получаем: $a \times b=-1.03376365 \times 10^9$ и $c \times d=-1.03376352 \times 10^9$. Выполняем вычитание, и получаем $-128$. Но если выполнить вычисления с двойной точностью, а в конце преобразовать их во float, то получится $-75.1656$. Что произошло?

Проблема в том, что значение каждого произведения может сильно выйти за нижнюю границу $-1 \times 10^9$, где расстояние между представимыми значениями с плавающей запятой очень велико — 64. То есть при округлении $a \times b$ и $c \times d$ по отдельности до ближайшего представимого float, они превращаются в числа, кратные 64. В свою очередь, их разность будет кратной 64, и не останется никакой надежды, что она станет к $-75.1656$ ближе, чем $-64$. В нашем случае результат оказался ещё дальше из-за того, как два произведения были округлены в $-1 \times 10^9$. Мы напрямую столкнёмся со старым добрым катастрофическим сокращением1.
Читать дальше →

WebAssembly: что и как

Reading time9 min
Views152K


Эта статья основана на моём выступлении на конференции ITSubbotnik, прошедшем 2 ноября 2019 года в Москве.


Вообще я бэкенд программист, но меня заинтересовала эта технология, она позволяет использовать мои знания бэкенда на фронте.


Проблема


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

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

Инкремент элементов вектора

Reading time13 min
Views17K
В каком случае инкремент элементов вектора std::vector будет быстрее – если они имеют тип uint8_t или uint32_t?

Чтобы не рассуждать отвлечённо, рассмотрим две конкретные реализации:

void vector8_inc(std::vector<uint8_t>& v)
{
  for (size_t i = 0; i < v.size(); i++)
  {
    v[i]++;
  }
}

void vector32_inc(std::vector<uint32_t>& v)
{
  for (size_t i = 0; i < v.size(); i++)
  {
    v[i]++;
  }
}
Попробуем угадать

Есть ли в CSS случайные числа?

Reading time5 min
Views8.2K
CSS позволяет создавать динамические макеты страниц и интерфейсы веб-проектов. Но CSS — статический язык. После того, как задано некое значение, изменить его нельзя. Идея случайного изменения неких значений здесь не рассматривается.



Генерирование случайных чисел — это территория JavaScript, на которую CSS не заходит. А что если это не совсем так? На самом деле, если принять в расчёт действия, выполняемые пользователем, это позволит добавить в CSS немного случайности. Автор материала, перевод которого мы сегодня публикуем, предлагает это обсудить.
Читать дальше →

Ожидаемые новые возможности JavaScript, о которых полезно знать

Reading time6 min
Views20K
С момента выхода стандарта ECMAScript 2015 (его ещё называют ES6) JavaScript серьёзно изменился и улучшился. Это очень хорошая новость для всех JS-разработчиков. Более того, теперь новая версия ECMAScript выходит каждый год. Возможно, вы не обратили особого внимания на то, что появилось в самой свежей версии стандарта, который был выпущен в июне 2019 года. Автор заметки, перевод которой мы сегодня публикуем, хочет в двух словах рассказать о новшествах JavaScript, и о том, чего можно ждать в следующей версии стандарта ECMAScript.



Здесь будут упомянуты возможности, предложения которых находятся на третьем этапе согласования (Stage 3). Это значит, что они, скорее всего, появятся в следующей версии стандарта ECMAScript, но с абсолютной достоверностью этого утверждать нельзя. Вот репозиторий, в котором можно найти сведения о предложениях, находящихся на разных этапах согласования.
Читать дальше →

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

Reading time12 min
Views4.1K

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


Кстати, знаете, что может ухудшить качество кодовой базы, полученной из последовательности идеальных pull request-ов? Тот факт, что сторонние программисты копировали в свои патчи куски существующего кода проекта вместо грамотного абстрагирования. Согласитесь, в какой-то мере такую банальность отловить ещё сложнее, чем некачественный код — он же качественный и даже уже тщательно отлаженный, поэтому тут недостаточно локальной проверки, нужно держать в голове всю кодовую базу, а человеку это непросто… Так вот: если на добавление полной поддержки Modelica (без создания конкретных правил) до состояния «может запускать примитивные проверки» у меня ушло около недели, то поддержку только copy-paste detector часто можно вообще добавить за день!

Узнать как...

Город засыпает, просыпаются хабровчане

Reading time4 min
Views24K
Если количество комментариев под статьёй стремительным домкратом приближается к 1000, будьте уверены — независимо от заявленной автором темы внутри бушует срач: очаги возгорания политоты, окружённые диванными экспертами по всем вопросам, психиатрические диагнозы на расстоянии по аватарке и никнейму, переходы на личности, саркастические выпады, едкость которых превышает таковую у крови ксеноморфов, и, конечно же, обязательное в таких случаях блюдо — взаимные обвинения в том, что ваш визави с вами дискутирует исключительно за вознаграждение и\или по долгу службы. Которая, видимо, и опасна и трудна, и на первый взгляд как будто не видна, а тридцать серебренников на дороге не валяются.

Самое забавное в такой ситуации это то,
Читать дальше →

Information

Rating
3,145-th
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity

Specialization

Fullstack Developer
Senior