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

А ключ к контролю и управлению это сбор и анализ информации.

Интересно в этом всём то, что Девэкспертс, который я постоянно хаю, в своё время предлогал мне научиться именно этому.

https://gist.github.com/mboes/040b60baa2b0e24ce668b6171db909c5

Только сегодня увидел - завтра сделаю.

Основная проблема это понять как соотносить путь 100м допустим с путём 10м в той же комнате.

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

И понять как обработать несколько источников.

Первые две проблемы можно по-другому рассмотреть. Можно рассматривать множество всех путей в квадрате и на этом множестве строить распределение вероятностней и плотность. Это самое рабочее.
Старый добрый матан)

P.S. Решил эту задачу. Результатом не доволен. То что раньше я бы сделал за пару часов, я делал несколько дней. Причины две: долго не начинал писать, всё медленно делаю.

https://github.com/nnizovkin2/Shortest_Path_In_Scalar_Field/
Разобрался, что такое монада.

Самое простое определять это через монойд эндофункторов для какой-либо категории.

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

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

Построение общей теории всего мы отбросим.

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

Голодный человек будет делать что-то, только до тех пор, пока не поест.

Горкавенко, привет.
X0 ->Y
 ➘ ➚
   X

f partitial function f: X -> Y
f defined in X0, subset of X

Drawing arrows in this direction entails the appearance of if statement in code.
if(f.isDefinedAt(v)) ...

f partitial function f: X -> Y
f defined in X0, subset of X
g partitial function g: Y -> Z
g defined in Y0, subset of Y

X2 →Y0→ Z
↓      ↓  ➚
X0→ Y
↓   ➚
X

In the case of composition, it becomes necessary to construct the intersection set of x0 and the preimage of f for Y0 set.

The construction of a preimage can be either impossible or difficult and not applicable in practice.

The solution for solving if and preimage problem was writen in this post(https://nnz2.dreamwidth.org/17932.html)
Я думаю, что мысли о том, что же находится между счётным и несчётным множеством и привели к идеи кванта. Волна даёт непрерывность, частица дискретность. Но это не точно)

Интересно, как множество, постороенное из точек представителей классов эквивалентности по рациональному расстоянию соотносится с квантами.

И интересно, что будет с этим множеством, если его взять и уменьшить ещё раз в мощность рационального множества раз.

Когда мы его строим мы именно это и делаем - делим отрезок [0, 1] в мощность рационального множества раз.

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

Интересно, что происходит на квантовой машине Тьюринга с np-полными задачами. Щас я думаю должны активно развиваться численные методы для квантовых компьютеров. Или даже просто набор операций, который мы можем сделать на такой машине. Архитектуры, компиляторы, выч. мат, обобщения - вообще всё. Это принципиально другой мир, другие вычисления и другие результаты.

И вот на таких машинах нейронные сети могут стать ИИ.
Квант в физике похож на множество между счётным и континуумом.
https://photos.app.goo.gl/EEjbwg8xsbWSi2c6A
Category.
Sets - objects
Arrows - functions

Code can look like this.
Every function wraps result with Either

Double f(Double d) case d >= 1 sqrt(d - 1)
Double g(Double d) case d <= 4 sqrt(4 - d)
print(g(f(1))).else(e -> print(e)) // print 2
print(g(g(-21))).else(e -> print(e)) // print stack trace with case condition and param on which we fell '5'

In Scala style it will be like this:
Either[Error, Double] f(Either[Error, Double] d) ...//match case etc


https://youtu.be/7aUJfDbyVSQ

P.S. Изобрёл исключения)
Ешь сколько хочешь, когда хочешь, что хочешь..


Пока есть деньги.
Касьянов ёбнутый идиот.
И это основное, что надо понимать.

Про Львова я честно говоря боюсь говорить. Зная его садистские наклонности.
Нельзя злиться на идиотов.

Нельзя бояться идиотов.
Фотоаппарат с определённым объективом фиксирует картинку лучше, чем человек.

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

Это просто ещё один инструмент.
В сухом остатке:
Я балабол и трус
Марианна блядь
Жених убийца старухи
В девекспертс не люди
Не каждая задача может быть решена эффективно с помощью точных и/или доказуемых методов.

Самое сложное в любой деятельности это работа с эвристиками.

ООП сложная область программирования, так как ООП и шаблоны это набор эвристик.

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

RISC CISC
DL ML
вычислительные методы vs символьные вычисления

https://www.google.com/search?q=plot+ml+vs+dl&client=ubuntu&hs=qrN&channel=fs&source=lnms&tbm=isch&sa=X&ved=2ahUKEwj406bN99fwAhV-CRAIHfKTDjgQ_AUoAXoECAEQAw&biw=1608&bih=949#imgrc=Gfd-hm87NLs98M
Посмотрел вот это видео. https://engineering.teads.com/tech-hub/
В голове осталась некоторая каша из-за композиции двух плохо знакомых мне языков(французкий, скала).

Потом посмотрел вот это видео. https://www.youtube.com/watch?v=57D-NYVIoRI
Тут всё просто и понятно.

Во-втором видео сущности попроще.

ФП более формализировано по сравнению с ООП.
ФП проще.
Потоковая обработка данных хорошо ложится в ФП парадигму.

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

Шаблоны проектирования, как и само ООП - набор эвристик.
В эвристиках нет ничего плохого.
Зачастую проблему можно решить более эффективно применяя эвристики, а не обобщенные методы.
В предыдущей статье я рассмотрел работу Шенандоа(https://nnz2.dreamwidth.org/9455.html)

ZGC поверхностно очень похож на c4 за исключением того, что в с4 присутствуют поколения.

Основное отличие c4 от Шенандоа в том, что первый использует read barrier, хранит forward pointer's в таблице, а не в шапке объекта и соответсвенно копирует в недавно собранные блоки, так как никому не нужны старые объекты(в шапках нет указателей). Также отсутствует сборка по поколениям.

А дальше идёт основная работа, которая связана с правильной работой с операционной системой и с железом. И это то, чем студенческий проект сборщика мусора, отличается от сборщиков в JDK.
Этот пидарок и жулик Витя просто безрукий идиот.

https://www.upwork.com/jobs/~013d9dad70ccff5a58
I need Kotlin or Java Encryption"AES , CBC mode " function to take :
String : 20276d22a19f07eaba8110010006aabbccddeeff010203040105060708090a0b0c0d0e0f111c
Key : 000102030405060708090a0b0c0d0e0f
Initial vector : 000102030405060708090a0b0c0d0e0f
as a input


package com.trash;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

//блядская функция
public class Main {

public static void main(String[] args) throws Exception {
String key = "000102030405060708090a0b0c0d0e0f";
String s = "20276d22a19f07eaba8110010006aabbccddeeff010203040105060708090a0b0c0d0e0f111c";
String initialVector = "000102030405060708090a0b0c0d0e0f";

System.out.println(encryptBSh(s, key, initialVector));
}

public static String encryptBSh(String s, String key, String initialVector) {
return byteArrayToHexString(encrypt(transformHexStringToByteArray(s),
transformHexStringToByteArray(key),
transformHexStringToByteArray(initialVector)));
}

public static byte[] encrypt(byte[] s, byte[] key, byte[] initialVector) {

IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

// Encrypt.
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

return cipher.doFinal(s);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException | InvalidKeyException e) {
throw new RuntimeException(e);
}
}

public static String byteArrayToHexString(byte[] array) {
byte[] res = new byte[array.length * 2];
for (int i = 0; i < array.length; i++) {
res[2 * i] = getAsciByteForDigit((byte) ((array[i] & 0xf0) >> 4));
res[2 * i + 1] = getAsciByteForDigit((byte) (array[i] & 0xf));
}

return new String(res, StandardCharsets.US_ASCII);
}

private static byte getAsciByteForDigit(byte d) {
return (byte) (d > 9 ? d - 10 + 'a' : d + '0');
}

public static byte[] transformHexStringToByteArray(String s) {
if (s.isEmpty()) {
return new byte[0];
}

byte[] sb = s.getBytes(StandardCharsets.US_ASCII);
byte[] res = new byte[sb.length / 2 + (sb.length & 1)];

for (int ri = sb.length - 1; ri >= 0; ri--) {
int i = sb.length - 1 - ri;

byte digit;
if (sb[ri] - '0' >= 0 && sb[ri] - '0' < 10) {
digit = (byte) (sb[ri] - '0');
} else if (sb[ri] - 'a' >= 0 && sb[ri] - 'a' < 6) {
digit = (byte) (sb[ri] - 'a' + 10);
} else {
throw new IllegalArgumentException();
}

res[res.length - 1 - i / 2] += (i & 1) == 0 ? digit : digit * 16;
}

return res;
}
}
Основное:
нужно тюнить - то что нужно тюнить.
Для этого нужно иметь профиль нагрузки и нужно уметь его снимать(yourkit).

Меньше выделять и собирать память.
Для этого:
1) Меньше создавать новые объекты(пулы объектов, сквозные объекты, примитивные типы?)
2) Использовать бинарные протоколы.
3) Не принимать и не обрабатывать лишние данные.

Уменьшить паузы при сборке мусора.
Для этого:
1) Выбрать low latency gc: zgc, shenandoah, с4?
2) Дать максимальное количество памяти.
3) для zgc, shenandoah включить большой размер страниц в линуксе.

https://docs.oracle.com/en/java/javase/16/docs/specs/man/java.html
https://wiki.openjdk.java.net/display/zgc/Main
https://eng.uber.com/jvm-tuning-garbage-collection/
Сборщик мусора:
Паралельный - может собирать мусор из нескольких потоков.
Конкурентный - не прерывает работу основного приложения.
Компактный - поддерживает пространственную локальность программы, если программа обладает этим свойством.
Программа обладает пространственной локальностью, если данные к которым было обращение недавно находятся рядом с данными, которые будут использованы сейчас.

Паралельность уменьшает время сборки мусора за счёт использования нескольких ядер.
Конкурентность даёт возможность приложению выпольнять работу во время сборки мусора.
Компактность поволяет оптимизировать время обращения к данным за счёт размещения данных, которые будут использованы "совместно", в кеше ядра или процессора, так же при определённой архитектуре(сейчас сборщики поддерживают оптимизацию для NUMA архитектуры(например поддерживается большинством топовых процессоров с архитектурой x86_64)) расположение таких данных в оперативной памяти ближе к используемому их ядру уменьшит время обращения к этим данным.

Сборщик мусора надо оценивать по следующим критериям:
стоимость
стабильность работы
время паузы приложения
работа с большими объёмами данных
удобство настройки
эффективное использование современной архитектуры
компактификация данных программы
пропускная способность
потребление ресурсов

Эти характеристики зависят одна от другой и улучшение одних характеристих может повлечь ухудшение других.

Распространённые сборщики мусора:
Serial gc - самое низкое потребление ресурсов. Эффективен для использования в embedded системах.
Parallel gc - обладает самой высокой пропускной способностью, эффективен для приложений где длина паузы неважна, а важна пропускная способность(пример батч обработка больших объёмов данных)
ZGC - низкое latency 1 миллисекунда
Shenandoah - низкое latency 1-10 миллисекунд
C4 - без пауз платный

Давайте более подробно рассмотрим бесплатные сборщики, которые используются для low latency приложений: ZGC, Shenandoah

Плюсы zgc, shenandoah: конкурентность и маленькая пауза на приостановку приложения, компактность, параллельность.

ZGC, Shenandoah приостанавливают работу приложения на незначительное время
Заявленные характеристики для ZGC до 1 миллисекунды в stop the world(STW)
Shenandoah от 1 до 10 миллисекунд

Достигается это за счёт конкуретной разметки достижимых объектов, с последующим конкурентным копированием в свободные регионы(Shenandoah), либо уплотнением используемых областей(ZGC).
В G1 была только конкурентная разметка.

Уплотнение позволяет в большинстве случаем уменьшить вероятность приостановки приложения(на Full GC) из-за недостаточного количества свободной памяти или аварийной остановки приложения с OutOfMemoryError.

Конкурентная разметка и сбор накладывают дополнительные расходы на выполнение кода приложения.
При присваивании или чтении ссылок из кучи(а = b.c, не a = b) происходит дополнительная проверка с дальнейшим выставлением барьера.

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

В ZGC в jdk16 сбор данных со стека происходит в конкурентном режиме.

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

Аглоритм Шенандоа:
1) Пауза
Собираем корневые объекты(со стэков, из статики, jni, whatever) и помечаем, как доступные.

2) Конкурентно размечаем граф объектов
Те необработанные объекты, на которые меняется ссылка с необработанного объекта на доступную ссылку(ссылка с доступного объекта, либо из корня), добавляются в очередь. Читаем эту очередь и помечаем эти объекты, как доступные и обходим их потомков.

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

Прекращаем маркировку, когда обошли весть граф и очередь уменьшилась до определённого размера, возможно до нулевого.

3) Пауза
Обрабатываем оставшиеся объекты в очереди.
Выгружаем неиспользуемые классы.
Выбираем те регионы, в которых больше всего мусора.

4) Конкурентно копируем объекты из выбранных регионов
Сборщик копируем объекты в новые блоки, при этом добавляя ссылку на новый объект, в заголовок старой копии.

Теперь мы можем читать объекты переходя по ссылке из старой копии.

Для сохранения консистентности, приложение может делать изменения только в новой копии. Чтобы не ждать копирования сборщиком - приложение само копирует объект, если это ещё не сделано.

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

5) Пауза: Cобираем ещё раз корневые объекты.

6) После этого конкуретно обходим граф и меняем ссылки во всех объектах со старых на новые.
Освобождаем все блоки со старыми объектами.

Конец.

Полезно прочитать вторую половину седьмой главы Ахо Ульмана.

Полезные ссылки:
https://docs.oracle.com/en/java/javase/16/docs/specs/man/java.html
https://wiki.openjdk.java.net/display/zgc/Main
https://wiki.openjdk.java.net/display/shenandoah/Main

https://malloc.se/blog/zgc-jdk16

https://www.researchgate.net/publication/306112816_Shenandoah_An_open-source_concurrent_compacting_garbage_collector_for_OpenJDK

https://go.azul.com/continuously-concurrent-compacting-collector
Page generated Jan. 17th, 2026 07:33 am
Powered by Dreamwidth Studios