@hirthwork

Тег programming в блоге hirthwork

hirthwork

"Duplication is cheaper than wrong abstraction" (c) https://www.sandimetz.com/b...he-wrong-abstraction
Не то чтобы я был согласен, но тезисы интересные

hirthwork

День, когда Х-ворк бросил переизобретать стандартную библиотеку.
Задача: отсортировать лексикографически массив массивов. Все внутренние массивы одинаковой длины в 500 интов. Массивов всего полмиллиона.

Наивная реализация: Arrays.sort(...), где в качестве компаратора объектов используется Arrays.compare(int[], int[]).
Отрабатывает за 30 мс. Для справки, внутри там Timsort

Снобская реализация: Не, ну как же это же можно Arrays.sort(...), там же постоянно будет пробегаться по каждому массиву чтобы сравнить, медленно работать будет, есть же сортировка Бентли-Седжвика, её впендюрим как крутые программисты. А чтобы быть ещё круче, сделаем с циклом, чтобы для самого длинного куска разбиения сортировать в этом же вызове функции, сэкономим на максимальной глубине стека вызовов.
Отрабатывает за 60мс. Ну нахуй эти ваши модные алгоритмы.

hirthwork

hirthwork

You either die a hero, or live long enough to write (char**) (void*) out

hirthwork

hirthwork

Что быстрее, два лукапа в таблице, switch на 22 case или «один лукап, один if и один shl»?

hirthwork

Допустим есть функция bool f(void** p), которая меняет где-то внутре делает *p = new_p;
Допустим есть конструкция:
if (f(&p) && f(&p)) {...}
Правильно ли я помню, что стандарт не гарантирует, в каком порядке будут вычислены оба &p и может оказаться так, что порядок вычислений может быть как &p f(..) &p f(..) так и &p &p f(..) f(..)?

hirthwork

Написал binary trie set. Скажите, как по научному этот велосипед называется?

hirthwork

Здравствуйте, мои маленькие любители поебатися с байткодом. Сегодня я вам расскажу о crucial difference различных access specifiers при объявлении мемберов inner-классов.
Слово в сторону: любой порядочный параноик объявит мембер своего класса как private, а не как либо ещё. Крайне ленивый раздолбай вообще access specifier не напишет. И вот тут-то и зарыта собака.
Возьмём вот такой класс с двумя inner-классами:

public class Main {
    class Inner {
        int field;
    }

    class Pinner {
        private int field;
    }

    int test(final Inner obj) {
        return obj.field;
    }

    int test(final Pinner obj) {
        return obj.field;
    }
}

Ничег сложного, просто два inner-класса, у одного поле int, у другого — private int. Ну и из двух разных функций обращаемся к этим полям.
Скомпилим и посмотрим на байткод:

$ javac Main.java
$ javap -p -c Main.class
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  int test(Main$Inner);
    Code:
       0: aload_1
       1: getfield      #2                  // Field Main$Inner.field:I
       4: ireturn

  int test(Main$Pinner);
    Code:
       0: aload_1
       1: invokestatic  #3                  // Method Main$Pinner.access$000:(LMain$Pinner;)I
       4: ireturn
}

Ну ничего себе! Было private int простое, а стало золотое — вместо банального getfield получаем invokestatic, который...

$ javap -p -c Main\$Pinner.class
Compiled from "Main.java"
class Main$Pinner {
  private int field;

  final Main this$0;

  Main$Pinner(Main);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #2                  // Field this$0:LMain;
       5: aload_0
       6: invokespecial #3                  // Method java/lang/Object."<init>":()V
       9: return

  static int access$000(Main$Pinner);
    Code:
       0: aload_0
       1: getfield      #1                  // Field field:I
       4: ireturn
}

... внутри уже сам делает getfield, т.е. на ровном месте получили лишний вызов функции. А ещё когда вы сделаете что-то вроде:

Pinner pinner = null;
return pinner.field;

То в стектрейсе NullPointerException вы получите лишний фрейм с этим самым Main$Pinner.access$000, который неопытного программиста просто вводит в ступор.

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

hirthwork

Тут возникла программисткая задачка совершенно отвязанная от реальных продуктовых задач.
Допустим есть класс A и у него есть функция-член a() (для простоты допустим, что она не виртуальная).
Есть иерархия классов, самым верхним родителем которой является класс A. (Например, класса B является наследником класса A, класс С является наследником класса B и класс D является наследником класса B). И таких классов ощутимо больше 26 шести штук.
Хочется: при конструировании объекта любого из этих классов автоматически вызывать A::a() после завершения работы конструктора. Т.е. при создании объекта класса C хочется, чтобы порядок вызова функций был такой: A::A(), B::B(), C::C(), A::a(). И при этом, чтобы ни в одном из наследников напрямую вызов A::a() не добавлять. И места их конструирования не менять.

Я бы сказал, что Java говно, но я даже на плюсах не знаю как это провернуть

hirthwork

Здравствуй, дорогой дневничок. Я заебался. Я себе сломал мозг об java.nio.ByteBuffer.
Чтобы не ломать каждый раз, сделал себе удобную пикчу, чтобы сразу было видно, что делает каждая операция.
Попробуйте и вы: https://tinystash.undef.im/...JZCFRvasdjVH7ze5.svg

hirthwork

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

hirthwork

Как конвертит булевое значение в число C++ developer?

bool flag = ...;
int value = flag;

Как конвертит булевое значение в число Java developer?

boolean flag = ...;
int value;
if (flag) {
   value = 1;
} else {
   value = 0;
}

Как конвертит булевое значение в число senior java C++ developer?

boolean flag = ...;
int value = 5 - Boolean.toString(flag).length();
hirthwork

В регулярках джавы можно сделать named capturing groups (если вы не знаете что это такое, то вам не сюда, а в кружок кройки и шитья), и по имени группы из Matcher'а можно доставать captured подстроку. Но при этом из скомпиленной регулярки нельзя достать список имён этих самых capturing groups, которые были заданы в регулярке. Второтег

hirthwork

Вот в паттерне observer как назвать класс, который уведомляет observer о смене состояния? Notifier, Reporter, Updater? Всё не то, имхо.

hirthwork

А посоветуйте какую-нибудь красивую библиотеку с mock HTTP сервером. А то я сегодня понял, что моя либа для mock'ов не позволяет удобно прописать зависимости обработки запросов между несколькими mock-серверами. Мне просто на архитектуру посмотреть для вдохновения.

hirthwork

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

hirthwork

Suffering Oriented Development: Don't build new technology until you feel the pain of not having it.

hirthwork

hirthwork

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

Добавить пост

Вы можете выбрать до 10 файлов общим размером не более 10 МБ.
Для форматирования текста используется Markdown.