Автор комментария выше, говоря о том что C# появился как копия Java, в чем-то прав. Многие ключевые фишки: динамическая память, gc, jit, generics, exceptions, annotations, web-servlets - C# реализовывал сразу же как они появлялись в Java, некоторые вещи (базовые методы, иерархия исключений) тоже сделаны по аналогии с Java. В принципе нет ничего в этом плохого, всякая идея откуда-то заимствуется.
Использование общих формулировок (БД, дисковая БД) может сбить с толку и дать полагать, что речь идет о любой СУБД, хотя речь в статье идет о СУБД Тарантул. В Postgres / Oracle / Mssql MVCC устроен хоть и схоже, но несколько иначе.
Т.е. будут дефолтные shared memory 128Мб и work memory 4Мб? И зачем тогда 256 Гб памяти в системе, для галочки?
посмотрели TPS в трех режимах — READ, WRITE, MIX
Если READ = простые select-ы, то особой работы cpu нет, это чтение из кеша бд или чтение с диска (через кеш ос).
Если WRITE = простые insert / update, то опять же особой работы cpu нет, это запись в wal и работа с буферами.
Работа cpu будет заметна в запросах с сортировками, агрегациями, аналитическими функциями. Потому без примеров данных и примеров запросов, подобные замеры не имеют особого смысла. Да, что-то измерили, но насколько это будет иметь пользу при выборе железа под нагрузку?
Использовал Ubuntu 22.10
А в чем преимущества перед debian, на основе которого ubuntu и собирается? Вы ведь не десктоп сборку накатываете.
Безусловно автор, Стивен Вольфрам, человек с глубоким пониманием сути вещей. Но написанный им текст воспринимать крайне сложно. Я имел некоторый опыт работы с марковскими сетями и многослойными перцептронами, с обучением распространением ошибки и градиентным спуском.. но мне было сложно читать этот текст. Вроде написано по-русски (переведено на русский), но порой целые абзацы текста не несут никакого смысла. Местами было ощущение, что этот текст и был сгенерирован ChatGPT или подобной системой.
Последовательность изложения материала показалась, мягко говоря, своеобразной: начали с генерации словосочетаний, прыгнули на генерацию н-грамм, потом ушли на распознавание чисел и немного про животных, потом про аттракторы и классификацию, потом про обучение, потом про эмбеддинг и группировку атрибутов, потом вернулись к генерации текстов.. пару десятков раз начинали абзацы, как же устроен ChatGPT.. ну и в конце лишь пришли к выводу, что устроен все сложно, сотни слоев, миллионы нейронов, миллиарды связей.. в части слоев есть некие руководители и механизмы обратной связи, но зачем они реально нужны никто не знает, главное, что работает.
Двоякое ощущение осталось от статьи: с одной стороны в ней есть полезная информация, с другой стороны, если вы знающий человек, то ничего полезного для вас в статье нет... а если вы новичок или человек со стороны, то скорее всего после прочтения статьи в голове у вас будет полный бардак.
Поначалу статья кажется интересной и полезной, но по прочтении особо полезного ничего и не остается.
Чувства
Зачем вашему коллегу выслушивать какие душевные переживания вы испытываете? Душевные переживания только ваши, а ситуацию каждый воспринимает сугубо индивидуально, и то, что для вас трагедия и конец мира, то для другого пустяковое дело, которое легко разрулить. Может вы просто раздуваете из мухи слона?
Наблюдения. ФИОЭ.
Допустим некоторые (!) Факты о некоторой ситуации вы можете как-то собрать, но логика обработки сломается уже на этапе Интерпретации. Вы не можете объективно проанализировать факты и оценить их, поскольку не знаете причин, приведших к Фактам. Чтобы как-то интерпретировать и оценивать надо собрать всю информационную базу.
Потребности
Вы исходите из предположения, что участники преследуют одни цели. Но это ведь далеко не так. Один работает за деньги, чтобы купить еду. Другой работает за идею сделать что-то значимое.
Просьбы
Это пожалуй единственное полезное в статье. Правильно выраженная просьба - уже половина дела.
Тоже обескуражила эта фраза, но скорее всего тут отсылка к тому, что пар готовится на ТЭС, работающей на природном газе, о чем идет речь десятком абзацев ниже.
У партнера подключаем скрипт виджета widget.js, инициализируем виджет, передавая селектор контейнера на странице партнера, ключ партнера для доступа к нашему апи:
На стороне своего сервиса конечно же настраиваем cors и делаем проверку ключа доступа. Таким образом мы явно ограничиваем круг партнеров, можем управлять доступом и отзывать доступ у тех, кто нарушил наши правила использования.
Не совсем понятен мотив использовать iframe для интеграции своего сервиса с партнерами. Не проще ли точно также добавлять партнерам ваш скрипт виджета и инициализировать виджет с указанием контейнера?
Люди любят придумывать новые названия (I-shape, T-shape) для уже имеющихся вещей: специалист узкого и специалист широкого профиля.
А если по теме. Специалистом широкого профиля становятся не по желанию, а эволюционно и органично развиваясь. Это происходит с годами (!) опыта. А если вы внезапно решили - вот я занимался бекендом, дай-ка я еще и фронт и базу подтяну, то хорошего из этого ничего не выйдет, будет каша и бардак в голове.
Не могу придумать ни одного реального случая, где мне бы потребовалось писать триггеры / хранимки на языке отличном от pl/sql, pl/pgsql и им подобным. Хранимки в бд стоит воспринимать как интерфейс доступа к данным. И если у вас появляется потребность в бд делать что-то сложное, то с вашей архитектурой явно что-то не так. А уж если появляется потребность в java в бд, это прямо вообще что-то не так.
Ну и раз речь про java. Без обид, но примеры кода стоило сделать более enterprose-ready: декомпозиция методов, try-with-resources, типизированные данные, а то примеры выглядят как ответы со стековерфлоу из нулевых.
Посыл статьи хороший, но в изложении какая-то каша. Скорее всего, это просто плохой перевод.
Элементы массива доступны по индексу ячейки.
Значение по умолчанию для ячеек – null
Для массивов объектов верно, для массивов примитивов значение зависит от типа компонента (для чисел 0, для булева false).
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) { ... }
Пожалуйста, не надо в 2022 году использовать итераторы в явном виде. Работа с итераторами может пригодится только в одном случае - удаление элементов. В остальных случаях for-each.
ArrayList list = new ArrayList() {{
add("Hello"); // быстрая инициализация
add(" world!");
}};
То, что тут raw-types, спишем на невнимательность. Но не надо так делать, вы же понимаете что тут неявно анонимный класс порождается?
Map – это массив на 16 buckets (корзин) – от 0 до 15.
Расширяется: 16 – 32 – 64 – и далее переходит к структуре red-black tree.
Во-первых, Map это интерфейс, а реализации у него: HashMap, TreeMap и т.д. Во-вторых, система бакетов и в правду применяется у HashMap, и в правду таблица бакетов расширяется до указанного предела 64.. но потом сами бакеты из связанного списка преобразуются в RB-дерево. Таблица бакетов никуда не девается.
Iterator iterator = set.iterator(); // итерация по элементам множества
while(iterator.hasNext()) { ... }
Аналогичное замечание, не надо вручную управлять итераторами.
Классы Hashable
Hashtable, как и упомянутый на диаграмме Vector надо забыть навсегда.
Пакет java.util.concurrent предоставляет реализации одновременных коллекций
Очень странный перевод. "Конкурентные коллекции" – это более чем понятное определение.
public int compare(Person p1, Person p2) {
return p1.uuid - p2.uuid;
}
Если не хотим словить баг, сравнение чисел надо делать через Integer.compare, или используя методы Comparator: compareInt, thenCompareInt.
Статья нагружена ненужными уточнениями, переводом javadoc с таблицей методов, устаревшими примерами кода... и возникает вопрос – ну и чего хотели добиться?
нет смысла вычислять степень... школьный курс математики говорит, что логарифм от степени, это произведение степени на логарифм, т.е.
$entropy = $value * log($set, 2);
это вас обезопасит от переполнения double в случае с большими числами.
Другой момент, то как вы вычисляете набор символов для энтропии. Первое, preg_match_all вообще не для этого придуман, и вам нужен простой preg_match. Второе, вы очень смело ограничили пароли только латиницей и странным набором спец. символов, словно другие наборы символов не могут быть использованы. Ну и третье, намного проще, и наверно даже правильней, собирать набор по самому паролю, т.е. вычислять просто кол-во уникальных символов в предоставленном пароле, полагая что злоумышленник знает этот набор.
Думаю, dynamicult имел ввиду мусор в синтаксисе языка – все эти $ :: \ := и т.п. В этом я с ним соглашусь.
Хороший синтаксис ЯП не должен обременять разработчика ненужными символами, не должен заставлять решать в голове ребусы, отвечая на вопрос "А что же тут происходит".
Вам как разработчику своего детища все эти хитровыдуманные символы и подходы очевидны и понятны. Но для других людей, которые вдруг внезапно захотят применить этот ЯП, это серьезный отталкивающий фактор.
Ну да, ну да, хотим похудеть и в порыве голода давайте кусочек масла съедим. Белок / клетчатка / грибы куда медленнее расщепляются и не приводят в отложениям в подкожно-жировой ткани. Потому считаю, лучше кусочек мяса погрызть, например, сушеного или вяленого, ну или морковку пожевать.
Я понимаю, что вы очарованы этой технологией, но мы дискутируем с вами о разном. Я выступаю за подход, когда транспорт (нижележащий слой абстракции) не зависит от приложения (вышележащий слой).
Также, я привел примеры, когда в разных ситуациях гранулярность изменений нужна своя - в одном случае сам файл принимается за атом, в другом строчка кода.
Ваш пример с CRDT впечатляет, не спорю, но применительно к разработке такая вещь подходит разве что для написания кода в реальном времени, этакое парное программирование онлайн. При таком написании кода кол-во изменений невелико и достаточно легко найти точки для сбора графа изменений. Но отойдите от примеров уровня hello world, напишите сотни и тысячи строк кода, растяните время синхронизации на часы и дни, и увидите полный фарш.
Git репо и его механизмы мержа устроены не просто из-за прихоти Торвальдса или его незнании CRDT, а из-за требований применимости. Код пишется чаще всего оффлайн, и ветки разработки могут жить разное время, часы, дни, а то и недели. И в такой ситуации гранулярность на уровне слов уже не сработает. Да что говорить, даже на уровне строк порой приходится резолвить конфликты и выискивать правду.
Подход интересный и имеет право на жизнь, но с чего вы взяли, что он должен применяться везде? Повторюсь еще раз, транспорт не должен зависеть от прикладной области. А в прикладной области может быть не нужна локализация изменений на уровне токенов (слов). Опять же, git работает на уровне строк, но если бы изменения мержились на уровне слов, то был бы полный фарш. Или заливка файлов, работает с файлом как единым целым, там не нужна грануляция содержимого в принципе. К чему это я – все зависит от прикладной области.
Как уже прокомментировали выше, набор инструкций (будь то jvm, cpu) ограничен и для расширения функционала создаются функции / модули / библиотеки. Integer.rotate точно бы не подошел, т.к. у него база 32 бита, а вам надо 8 бит, потому какой-нить Byte.rotate пригодился бы. Создайте PR в проект OpenJDK и возможно его примут.
CRDT работает для примитивов (чисел), и даже для них необходимо явное указание merge функции (например, max).
В случае текстов это не работает. Простой логический эксперимент, двое людей загрузили состояние объекта С0 и сделали правки: С1 и С2.. как их смержить между собой? В общем общем случае - никак. Можно лишь найти ухищрения, сузить области изменений. Например, если первый правил в одном абзаце, а второй во втором, то все легко мержится. Или если сузить область до уровня строк (как и делает git merge), и тогда построчно смотреть, что добавилось, а что изменилось.
И опять же, это уровень приложения, не транспорта. Потому что данные могут быть какие угодно.
Автор комментария выше, говоря о том что C# появился как копия Java, в чем-то прав. Многие ключевые фишки: динамическая память, gc, jit, generics, exceptions, annotations, web-servlets - C# реализовывал сразу же как они появлялись в Java, некоторые вещи (базовые методы, иерархия исключений) тоже сделаны по аналогии с Java. В принципе нет ничего в этом плохого, всякая идея откуда-то заимствуется.
Использование общих формулировок (БД, дисковая БД) может сбить с толку и дать полагать, что речь идет о любой СУБД, хотя речь в статье идет о СУБД Тарантул. В Postgres / Oracle / Mssql MVCC устроен хоть и схоже, но несколько иначе.
Т.е. будут дефолтные shared memory 128Мб и work memory 4Мб? И зачем тогда 256 Гб памяти в системе, для галочки?
Если READ = простые select-ы, то особой работы cpu нет, это чтение из кеша бд или чтение с диска (через кеш ос).
Если WRITE = простые insert / update, то опять же особой работы cpu нет, это запись в wal и работа с буферами.
Работа cpu будет заметна в запросах с сортировками, агрегациями, аналитическими функциями. Потому без примеров данных и примеров запросов, подобные замеры не имеют особого смысла. Да, что-то измерили, но насколько это будет иметь пользу при выборе железа под нагрузку?
А в чем преимущества перед debian, на основе которого ubuntu и собирается? Вы ведь не десктоп сборку накатываете.
Безусловно автор, Стивен Вольфрам, человек с глубоким пониманием сути вещей. Но написанный им текст воспринимать крайне сложно. Я имел некоторый опыт работы с марковскими сетями и многослойными перцептронами, с обучением распространением ошибки и градиентным спуском.. но мне было сложно читать этот текст. Вроде написано по-русски (переведено на русский), но порой целые абзацы текста не несут никакого смысла. Местами было ощущение, что этот текст и был сгенерирован ChatGPT или подобной системой.
Последовательность изложения материала показалась, мягко говоря, своеобразной: начали с генерации словосочетаний, прыгнули на генерацию н-грамм, потом ушли на распознавание чисел и немного про животных, потом про аттракторы и классификацию, потом про обучение, потом про эмбеддинг и группировку атрибутов, потом вернулись к генерации текстов.. пару десятков раз начинали абзацы, как же устроен ChatGPT.. ну и в конце лишь пришли к выводу, что устроен все сложно, сотни слоев, миллионы нейронов, миллиарды связей.. в части слоев есть некие руководители и механизмы обратной связи, но зачем они реально нужны никто не знает, главное, что работает.
Двоякое ощущение осталось от статьи: с одной стороны в ней есть полезная информация, с другой стороны, если вы знающий человек, то ничего полезного для вас в статье нет... а если вы новичок или человек со стороны, то скорее всего после прочтения статьи в голове у вас будет полный бардак.
Поначалу статья кажется интересной и полезной, но по прочтении особо полезного ничего и не остается.
Зачем вашему коллегу выслушивать какие душевные переживания вы испытываете? Душевные переживания только ваши, а ситуацию каждый воспринимает сугубо индивидуально, и то, что для вас трагедия и конец мира, то для другого пустяковое дело, которое легко разрулить. Может вы просто раздуваете из мухи слона?
Допустим некоторые (!) Факты о некоторой ситуации вы можете как-то собрать, но логика обработки сломается уже на этапе Интерпретации. Вы не можете объективно проанализировать факты и оценить их, поскольку не знаете причин, приведших к Фактам. Чтобы как-то интерпретировать и оценивать надо собрать всю информационную базу.
Вы исходите из предположения, что участники преследуют одни цели. Но это ведь далеко не так. Один работает за деньги, чтобы купить еду. Другой работает за идею сделать что-то значимое.
Это пожалуй единственное полезное в статье. Правильно выраженная просьба - уже половина дела.
Тоже обескуражила эта фраза, но скорее всего тут отсылка к тому, что пар готовится на ТЭС, работающей на природном газе, о чем идет речь десятком абзацев ниже.
У партнера подключаем скрипт виджета widget.js, инициализируем виджет, передавая селектор контейнера на странице партнера, ключ партнера для доступа к нашему апи:
На стороне своего сервиса конечно же настраиваем cors и делаем проверку ключа доступа. Таким образом мы явно ограничиваем круг партнеров, можем управлять доступом и отзывать доступ у тех, кто нарушил наши правила использования.
Не совсем понятен мотив использовать iframe для интеграции своего сервиса с партнерами. Не проще ли точно также добавлять партнерам ваш скрипт виджета и инициализировать виджет с указанием контейнера?
Люди любят придумывать новые названия (I-shape, T-shape) для уже имеющихся вещей: специалист узкого и специалист широкого профиля.
А если по теме. Специалистом широкого профиля становятся не по желанию, а эволюционно и органично развиваясь. Это происходит с годами (!) опыта. А если вы внезапно решили - вот я занимался бекендом, дай-ка я еще и фронт и базу подтяну, то хорошего из этого ничего не выйдет, будет каша и бардак в голове.
Да, нам очень интересно мнение самоучки с нулевым опытом коммерческой разработки.
И конечно же, у любого самоучки во дворе стоит Tesla... почему бы и да.
Не могу придумать ни одного реального случая, где мне бы потребовалось писать триггеры / хранимки на языке отличном от pl/sql, pl/pgsql и им подобным. Хранимки в бд стоит воспринимать как интерфейс доступа к данным. И если у вас появляется потребность в бд делать что-то сложное, то с вашей архитектурой явно что-то не так. А уж если появляется потребность в java в бд, это прямо вообще что-то не так.
Ну и раз речь про java. Без обид, но примеры кода стоило сделать более enterprose-ready: декомпозиция методов, try-with-resources, типизированные данные, а то примеры выглядят как ответы со стековерфлоу из нулевых.
Я в своем комментарии упоминал, используем современные методы Comparator
Посыл статьи хороший, но в изложении какая-то каша. Скорее всего, это просто плохой перевод.
Для массивов объектов верно, для массивов примитивов значение зависит от типа компонента (для чисел 0, для булева false).
Пожалуйста, не надо в 2022 году использовать итераторы в явном виде. Работа с итераторами может пригодится только в одном случае - удаление элементов. В остальных случаях for-each.
То, что тут raw-types, спишем на невнимательность. Но не надо так делать, вы же понимаете что тут неявно анонимный класс порождается?
Во-первых, Map это интерфейс, а реализации у него: HashMap, TreeMap и т.д. Во-вторых, система бакетов и в правду применяется у HashMap, и в правду таблица бакетов расширяется до указанного предела 64.. но потом сами бакеты из связанного списка преобразуются в RB-дерево. Таблица бакетов никуда не девается.
Аналогичное замечание, не надо вручную управлять итераторами.
Hashtable, как и упомянутый на диаграмме Vector надо забыть навсегда.
Очень странный перевод. "Конкурентные коллекции" – это более чем понятное определение.
Если не хотим словить баг, сравнение чисел надо делать через Integer.compare, или используя методы Comparator: compareInt, thenCompareInt.
Статья нагружена ненужными уточнениями, переводом javadoc с таблицей методов, устаревшими примерами кода... и возникает вопрос – ну и чего хотели добиться?
Не примите за личное, но в:
нет смысла вычислять степень... школьный курс математики говорит, что логарифм от степени, это произведение степени на логарифм, т.е.
это вас обезопасит от переполнения double в случае с большими числами.
Другой момент, то как вы вычисляете набор символов для энтропии. Первое, preg_match_all вообще не для этого придуман, и вам нужен простой preg_match. Второе, вы очень смело ограничили пароли только латиницей и странным набором спец. символов, словно другие наборы символов не могут быть использованы. Ну и третье, намного проще, и наверно даже правильней, собирать набор по самому паролю, т.е. вычислять просто кол-во уникальных символов в предоставленном пароле, полагая что злоумышленник знает этот набор.
Думаю, dynamicult имел ввиду мусор в синтаксисе языка – все эти $ :: \ := и т.п. В этом я с ним соглашусь.
Хороший синтаксис ЯП не должен обременять разработчика ненужными символами, не должен заставлять решать в голове ребусы, отвечая на вопрос "А что же тут происходит".
Вам как разработчику своего детища все эти хитровыдуманные символы и подходы очевидны и понятны. Но для других людей, которые вдруг внезапно захотят применить этот ЯП, это серьезный отталкивающий фактор.
Ну да, ну да, хотим похудеть и в порыве голода давайте кусочек масла съедим. Белок / клетчатка / грибы куда медленнее расщепляются и не приводят в отложениям в подкожно-жировой ткани. Потому считаю, лучше кусочек мяса погрызть, например, сушеного или вяленого, ну или морковку пожевать.
Я понимаю, что вы очарованы этой технологией, но мы дискутируем с вами о разном. Я выступаю за подход, когда транспорт (нижележащий слой абстракции) не зависит от приложения (вышележащий слой).
Также, я привел примеры, когда в разных ситуациях гранулярность изменений нужна своя - в одном случае сам файл принимается за атом, в другом строчка кода.
Ваш пример с CRDT впечатляет, не спорю, но применительно к разработке такая вещь подходит разве что для написания кода в реальном времени, этакое парное программирование онлайн. При таком написании кода кол-во изменений невелико и достаточно легко найти точки для сбора графа изменений. Но отойдите от примеров уровня hello world, напишите сотни и тысячи строк кода, растяните время синхронизации на часы и дни, и увидите полный фарш.
Git репо и его механизмы мержа устроены не просто из-за прихоти Торвальдса или его незнании CRDT, а из-за требований применимости. Код пишется чаще всего оффлайн, и ветки разработки могут жить разное время, часы, дни, а то и недели. И в такой ситуации гранулярность на уровне слов уже не сработает. Да что говорить, даже на уровне строк порой приходится резолвить конфликты и выискивать правду.
Подход интересный и имеет право на жизнь, но с чего вы взяли, что он должен применяться везде? Повторюсь еще раз, транспорт не должен зависеть от прикладной области. А в прикладной области может быть не нужна локализация изменений на уровне токенов (слов). Опять же, git работает на уровне строк, но если бы изменения мержились на уровне слов, то был бы полный фарш. Или заливка файлов, работает с файлом как единым целым, там не нужна грануляция содержимого в принципе. К чему это я – все зависит от прикладной области.
Как уже прокомментировали выше, набор инструкций (будь то jvm, cpu) ограничен и для расширения функционала создаются функции / модули / библиотеки. Integer.rotate точно бы не подошел, т.к. у него база 32 бита, а вам надо 8 бит, потому какой-нить Byte.rotate пригодился бы. Создайте PR в проект OpenJDK и возможно его примут.
CRDT работает для примитивов (чисел), и даже для них необходимо явное указание merge функции (например, max).
В случае текстов это не работает. Простой логический эксперимент, двое людей загрузили состояние объекта С0 и сделали правки: С1 и С2.. как их смержить между собой? В общем общем случае - никак. Можно лишь найти ухищрения, сузить области изменений. Например, если первый правил в одном абзаце, а второй во втором, то все легко мержится. Или если сузить область до уровня строк (как и делает git merge), и тогда построчно смотреть, что добавилось, а что изменилось.
И опять же, это уровень приложения, не транспорта. Потому что данные могут быть какие угодно.