Обновить
39

Пользователь

1,1
Рейтинг
8
Подписчики
Отправить сообщение

Использовать слово "антипаттерн" - это антипаттерн. А уж настолько облениться, что прогонять ответ на комментарий через LLM - это супер-антипаттрн.

Где вы набираетесь этой манеры излагать: с драматизацией, с громкими словами, с пафосом? Это звучит как клоунство. На конференциях что ли? По тону сразу чувствуется, что тебе будут что-то продавать, нахваливая достоинства, скрывая проблемы и недостатки.

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

Уж ответил так ответил, просто размазал аргументацией.

В целом статья вроде норм, но было бы лучше, если бы часть "pub/sub решит все ваши проблемы" была поменьше.

Нет, это разные люди. "Отрепьев" был либеральных взглядов, а "Георгий" - социалистических. Ещё я бы сказал, что "Отрепьев" лет на 10 моложе, более агрессивный, активный и конкретный. А "Георгий" любит глобальные темы, и все его "атаки" - это защиты.

Первая часть статьи: какая-то каша из цитат разных авторов.

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

На графиках видно, что степень сжатия lossless-кодеками составляет 40%-70% от исходного wav-файла. Формат mp3 сжимает сильно лучше (15%-25%), на его фоне остальные смотрелись бы бледно. Все ухищрения, описанные в статье, влияют на скорость запаковки-распаковки и на вычислительную нагрузку, а не на степерь сжатия.

Статью минусанул, автору карму не стал минусить, ибо какой он, нахрен, автор? Этот LLM-ный текстосодержащий продукт не должен тут оставаться.

Добрый человек, расскажи, пожалуйста, про ноги и педали, это доставляет мне максимальный дискомфорт. У меня не получается держать пятку на полу и жать носком, я полностью поднимаю ногу и давлю. И при этом не могу точно контролировать силу нажатия. Есть техники, чтобы лучше управляться с педалями?

Есть стойкое ощущение, что вы очень хотите поспорить, и совсем не хотите понять (ну и на текущий момент не понимаете функциональщину). Из-за этого ваш спор сводится к цитированию википедии, апелляциям к "общепринятым терминам" и спорам о словах. Если вдруг захотите понять, то дайте знать, тогда будет смысл. А сейчас не интересно. Я поражаюсь терпеливости IU.

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

Операция над элементами полугруппы обязательно должна обладать свойством ассоциативности

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

Статья получилось разделённой на две не связанные части: одна про полугруппы, другая про функторы, а описание монады в конце осталось подвешенным, просто flatMap из Array. Хотя нужно совсем немного, чтобы сделать статью цельной и понятной: нужно объявить Array полугруппой, операцией будет конкатенация. Тогда fold будет соединять массивы в массиве, получится тот же flatMap. А монаду определить через fold, соединив функторы и полугруппы.

Наш клиент (ООО "Х") занимается организацией обучения за рубежом.

на следующий день громкие заголовки в СМИ, мол такая-то компания оштрафована за сотрудничество с нежелательным иностранным ВУЗом

Отличная реклама получилась

Я нифига не понял аргументации. Функции плохо подходят для отложенных вычислений, потому что есть частный случай: анонимные функции плохо пригодны для сериализации-десериализации, потому что захватывают контекст. Но АСТ тоже не захватывает контекст! А во-вторых, есть простейшие рефакторинги: сделать функцию не-анонимной, передавать аргумент в явном виде.

Дальше был первый пример кода, и тут мне непонятно: а "матчер" - это что? Выглядит как синтаксический сахар для функции x -> boolean . Какой это тип?

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

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

Но есть ещё один момент. В функциональных языках поддерживаются значения-функции, которые запомнили контекст, в котором были определены, включая локальные переменные этого контекста. Такое хранилище контекста функции называется "замыкание"/"closure", и, поскольку для него порядок создания не соответствует обратному порядку удаления, оно создаётся на куче. А раз уж там живут локальные переменные, то имеет смысл его использовать в качестве кадра локальных переменных функции.

Блин, где вы отрыли фотографию МакКарти без бороды? На каноничных фотографиях он с шикарной бородищей и шевелюрой.

Как-то маловато. Этот прототип нельзя назвать HTTP-сервером, потому что тут нет парсинга HTTP, оно на любой однобайтный коннект сработает. А парсинг HTTP - это же самое интересное, потому что напрямую влияет на работу с NIO. Например, в handleRequest() зачем-то каждый раз аллоцируется ByteBuffer, хотя содержимое HTTP-запроса может приходить несколькими кусками. Правильный способ - привязывать ByteBuffer к socketChannel-у, и умело работать с ByteBuffer-ом через compact()/flip(). А по этой статье вообще не ясно, зачем flip() вызвали.

Ну и так, пара косяков. Первое: вы закрываете socketChannel, но оставляете его SelectionKey в Selector-е, это неправильно, нужно на ключе делать cancel(). Второе: вы делаете write() на неблокирующем канале, и даже не проверяете записалось оно или нет.

Спектрум был неплохой машиной для игр и обучения программированию, но разрабатывать на нём и сразу на месте тестироваться было больно: ассемблер и исходники программы занимали память, которой и так было немного, плюс программа могла зависнуть, погубив среду разработки. Из-за этого для разработки использовали разные непростые и недешёвые варианты. Вот тут утверждают, что у Ultimate было что-то типа многопользовательской Unix-машины на 68000 с кросс-компиляцией. Эх, нигде нет деталей.

Согласен, насчёт константости - скорее всего враньё. А насчёт скорости: если посмотреть документацию на vers-vecs , то там написано

This crate uses compiler intrinsics for bit manipulation. The intrinsics are supported by all modern x86_64 CPUs, but not by other architectures. There are fallback implementations if the intrinsics are not available, but they are significantly slower. Using this library on x86 CPUs without enabling BMI2 and popcnt target features is not recommended.

The intrinsics in question are popcnt (supported since SSE4.2 resp. SSE4a on AMD, 2007-2008), pdep (supported with BMI2 since Intel Haswell resp. AMD Excavator, in hardware since AMD Zen 3, 2011-2013), and tzcnt (supported with BMI1 since Intel Haswell resp. AMD Jaguar, ca. 2013).

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

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

Ага, говорили. И это, конечно же, не было опровергнуто в статье.

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

Я проверил это так. Написал пару классов:

public class Parent {
  private final String name;
  public Parent(String name) { this.name = name;}
  public String getParentName() { return name;}
}

public class Child extends Parent {
  private String myName;
  public Child(String childName, String parentName) {super(parentName);this.myName=childName;}
  public String getFullName() { return "I am " + myName + " , a child of a " + getParentName();}
  public static void main(String[] args) {
    Child child = new Child("ChildClass","ParentClass");
    System.out.println(child.getFullName());
  }
}

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

  public Child(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: aload_0
         1: aload_2
         2: invokespecial #1                  // Method Parent."<init>":(Ljava/lang/String;)V
         5: aload_0
         6: aload_1
         7: putfield      #7                  // Field myName:Ljava/lang/String;
        10: return
      LineNumberTable:
        line 3: 0

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

public Child(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: aload_0
         1: aload_1
         2: putfield      #7                  // Field myName:Ljava/lang/String;
         5: aload_0
         6: aload_2
         7: invokespecial #1                  // Method Parent."<init>":(Ljava/lang/String;)V
        10: return
      LineNumberTable:
        line 3: 0

И всё отлично работает.

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

Эта статья вызвала мой интерес не тем, что она про нейросети, а видом сжатого С-кода. Дело в том, что очень похожий стиль принят среди разработчиков на языках k и q, и интерпретаторы этих языков часто пишут в таком сжатом стиле, который мне даётся с трудом. Я подумал, что ну вот, может тут расскажут, как писать такое, поделятся секретами. А нифига, я сходил на github, и там исходники лежат в гораздо более понятном виде, и питоновский скрипт, который выполняет сжатие. Но при ближайшем рассмотрении оказалось, что питоновский скрипт делает довольно тупые действия, и автору в основном исходнике приходится самому прибегать к препроцессорной магии.

Когда я дошёл до раздела, где объясняется препроцессорная магия для матрично-скалярных и матрично-матричных операций, я сначала нифига не понимал, до тех пор, пока исходники не почитал. Дело в том, что в тексте вроде как define-ится BINARY с двумя аргументами (function и operation) в нижнем регистре, а потом в теле этого BINARY эти же аргументы стоят в верхнем регистре (FUNCTION и OPERATION), это очень сбивает с толку. Это не проблема перевода, в оригинальном тексте тоже так, в исходниках всё норм (fn и opr везде). Ну и раз уж зашла речь про BINARY, то я бы в начале проверил, что размеры матриц совпадают, fail fast и всё такое. Забавно, что он вводит поэлементное умножение и деление матриц, я такого не видел в математике, но у него находит применение в LayerNorm.

В описании математического матричного умножения у автора тоже косяк, в первом, неоптимизированном варианте остались k2 и j2.

Информация

В рейтинге
1 930-й
Зарегистрирован
Активность