• Конференция Joker 2017: удивительные истории
    +1

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

  • Конференция Joker 2017: удивительные истории
    +1

    Пока вроде не присылали обратную связь.

  • Анонс Java-конференции JPoint 2018: JDK 9, высокие нагрузки и производительность JVM
    +2

    Да, просто баннер без людей, без свага :(

  • Анонс Java-конференции JPoint 2018: JDK 9, высокие нагрузки и производительность JVM
    +2

    Библиотеки потихоньку мигрируют, потому что они библиотеки.

  • Анонс Java-конференции JPoint 2018: JDK 9, высокие нагрузки и производительность JVM
    +3

    Вот денусь куда-нибудь и будете знать! Останетесь без паззлеров!

  • Анонс Java-конференции JPoint 2018: JDK 9, высокие нагрузки и производительность JVM
    +12

    Кстати, забыл спросить: а чо так дорого-то?!

  • Анонс Java-конференции JPoint 2018: JDK 9, высокие нагрузки и производительность JVM
    +10

    Отлично работаете, правильных людей приглашаете! Надо будет съездить послушать ;-)

  • Назад в будущее: как прошёл Joker 2017
    +1

    Поддерживаю, он крутой :-)

  • Назад в будущее: как прошёл Joker 2017
    0

    Ну это как раз нормально. В лобби было полно места, поэтому я бы не назвал это каким-то уж страшным вынуждением. Напитки можно было с собой выносить в лобби. Я и поговорить успел, и попрыгал. Так что тут вполне ок. Во всяком случае гораздо лучше, чем тот ад с офисом СберТеха, который был на JPoint :D

  • Назад в будущее: как прошёл Joker 2017
    0

    Да, репертуар был какой-то весьма попсовый. Хотя эти ребята играют и вещи посерьёзнее.

  • Назад в будущее: как прошёл Joker 2017
    +2
    откровенно говоря таковыми не являлись (например, «Тестирование lock-free алгоритмов» или «Birth, life and death of a class»).

    Ммм… Насчёт Birth, life and death of a class не соглашусь. Разве что если вы ушли через 20 минут после начала, тогда ок, начало действительно было лайтовым. Если вам действительно весь доклад показался лёгким, объясните мне историю с классами A и B. Она мне мозг взорвала, я так и не вник в последнюю модификацию.

  • Назад в будущее: как прошёл Joker 2017
    +3
    у Тагира даже на слайдах совсем другого доклада при большом желании можно найти «стрим».

    Подкололи! Я и сам не заметил :D

  • Назад в будущее: как прошёл Joker 2017
    +3

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

  • Generic исключения в лямбда-функциях
    0

    Ну-ну.


    Function<File, Document> fn = rethrowFunction(DocumentFactory::newFileDocument);
    
    List<Document> documents = filesModel.getFiles().values().stream()
                    .map(fn)
                    .collect(toList());

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

  • Generic исключения в лямбда-функциях
    +1

    У вашего подхода одна существенная проблема: таким образом нельзя сделать ленивые стримы. А Stream API лениво по спецификации. Фактически все действия выполняет терминальная операция (например, collect), а вовсе не промежуточная типа map. Поэтому именно терминальная и будет кидать ваше исключение. Причём если стрим параллельный, оно может быть транслировано из другого потока.

  • Generic исключения в лямбда-функциях
    0

    Это бред. Никогда не кидайте checked-исключение там, где оно не объявлено. Иначе оно улетит туда, где его никто не будет ждать. Это может быть удобно в трёхстрочных программах, но в серьёзном проекте вы потом не обрадуетесь, когда логи будете читать и баг-репорты разгребать.

  • Как отлаживать маленькие программы
    0

    Ну вы же понимаете, что статья не о тех случаях, о которых вы говорите? :-)

  • Как отлаживать маленькие программы
    0

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


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

  • Как отлаживать маленькие программы
    0

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

  • Как отлаживать маленькие программы
    +3
  • Смарт контракты Ethereum: пишем простой контракт для ICO
    +1

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

  • Смарт контракты Ethereum: пишем простой контракт для ICO
    0
    стоимость выполнения тех или иных операций (выраженная в деньгах)

    В идеале об этом должен компилятор думать. Он должен это измерять, компилировать, оптимизируя именно эту стоимость, выдавать вам советы в виде предупреждений и т. д. В светлом будущем, наверно, так и будет :-)

  • Смарт контракты Ethereum: пишем простой контракт для ICO
    +2
    Нет, предполагалась логика именно плавучки и не иначе.

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

  • Смарт контракты Ethereum: пишем простой контракт для ICO
    +1
    Автор(комментария) предлагает взять из копеек сделать рубли в рамках целых чисел

    Где я это предлагал? Я предлагал не работать с голыми числами вообще, ни с целыми, ни с дробными. Их надо видеть только в точках взаимодействия с внешними системами. А там уже тип зависит от того, который навязан внешней системой. Я ничего не говорил ни про целые, ни про дробные, ни про пару. Объект класса Amount может всё внутри переводить в ваши любимые вэи, может использовать дробные числа, может хранить пару, это без разницы. В этом суть абстракции. Завтра точности вэев станет недостаточно, поделят их ещё в тысячу раз и что тогда? Если у вас код абстрагирован от представления, поменять придётся только один класс.

  • Смарт контракты Ethereum: пишем простой контракт для ICO
    +2
    Если вам это нравиться — так и пишите, но про «должны» — забудьте.

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


    Выражения про плавучку абсолютно не понимаю. При чём здесь какая-то плавучка? Я говорю, численное представление суммы должно быть абстрагировано. Неважно, что там внутри. А вы мне про какую-то плавучку. Я и слов-то таких не употребляю никогда.


    Жава не поддерживает, как и 99% языков. Что дальше?

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


    Язык он про сложение чиселок. Так везде.

    Какое-то у вас примитивное представление о программировании. Либо вы на ассемблере всю жизнь пишете, тогда простительно.


    Такого компилятора у жавы нет, как и у 99% языков. Что же с этим поделать? Откуда он должен взяться тут?

    Джавовый JIT (Hotspot C2) вполне способен на такие оптимизации. Я полагаю, Clang с кодом на C++ легко разделается тоже. Тут вполне тривиальная цепочка оптимизаций инлайнинга, эскейп-анализа и констант-фолдинга. Это всё в теории компиляции известно десятилетиями. Не знаю, что там в солидити, но учитывая, какие деньги крутятся в этериуме, хорошего компиляторщика нанять не должно быть большой проблемой.


    Смысл последнего абзаца в том, что этериум = джаваскрипт и ничего с этим не поделаешь? Я думаю, в основу платформы никакая типизация не заложена и на ней вполне можно сделать нормальный язык, компилируемый в этериум. Либо он уже существует, просто автор этой статьи не умеет им пользоваться.

  • Смарт контракты Ethereum: пишем простой контракт для ICO
    +1

    1 ether получше, чем восемнадцать нулей, хотя скрывается тот факт, что оно выражено в веях. Возможно, это ничего, если все привыкли считать, что всё и всегда выражено в веях. Но оно опять же явно не так. В коде автора, например, есть tokensPerOneEther = 5000, а вовсе не цена одного токена в веях. Очевидно, что не всегда удобно работать с веями, надо с разными единицами уметь.

  • Смарт контракты Ethereum: пишем простой контракт для ICO
    +17

    Смотрю с точки зрения обычного программиста. В ваших смартконтрактах реально принято код загружать такими константами вида 1000000000000000000? Ведь это какое-то наивное детское программирование, хоть и называется громким словом solidity. Это неправильно на кучу слоёв.


    Слой 1. Можно легко пропустить где-нибудь нолик или неправильно их сосчитать и неправильно понять код. Язык должен позволять писать 1_000_000_000_000_000_000. Если позволяет, программисты должны этим пользоваться.


    Слой 2. Это всё равно неправильно, потому что вероятность ошибки с пропуском нолика существует до сих пор. Должна существовать предопределённая именованная константа вроде WEI_PER_ETHER = 1_000_000_000_000_000_000, и в коде должна использоваться только она. Тогда станет понятнее, что происходит и вероятность ошибки ещё снизится.


    Слой 3. И это всё равно неправильно, потому что можно неправильно сделать вычисления. Например, умножить там, где надо разделить, передав не 10-18, а 10+18 попугаев. Нужны предопределённые функции или макросы с понятными именами вроде convertWeiToEther(weiAmount) и convertEtherToWei(etherAmount).


    Слой 4. И это всё равно неправильно, потому что можно по ошибке забыть вызвать макрос. Должна быть объектная типизированная модель, исключающая возможность присваивания неправильного значения. Что-нибудь вроде WEI.amount(uint256 value) возвращает объект типа Amount, и чтобы получить сумму в эфире, надо вызвать WEI.amount(value).toEther(). При этом не следует использовать сырые значения в числах слишком часто, только в исключительных случаях вроде окончательного обмена данными с внешним источником. В идеале это должно быть спрятано в методах родительских контрактов и всякие msg.value уже должны иметь тип Amount и писать надо msg.value.subtract(MY_TOKEN.amount(tokens)), где константа Currency MY_TOKEN = createStableCurrency(Ether.amount(1/5000)). Я придерживаюсь синтаксиса джавы, но это необязательно. Язык может и перегрузку операторов поддерживать, тогда можно писать msg.value - MY_TOKEN.amount(tokens), но при этом компиляция не пролезет, если попытаетесь эфир вычесть из токенов или сложить токены с веями.


    Пока всё выглядит так, что детям дали бомбой поиграться. И не надо рассказывать мне про стоимость исполнения на Etherium VM. Хороший оптимизирующий компилятор можно выкинуть все эти слои абстракций, сгенерировав точно такой же конечный код.

  • Причуды Stream API
    +1

    Нет. Тут сперва создаётся стрим из одного элемента и флэтмэпится на миллион. В этом и суть.

  • Причуды Stream API
    +5

    Если что, картинки для «причуд» я надёргал с интернета вечером перед докладом, потому что мне показалось, что презентация скучновата. Не уверен, что это было правильное решение.

  • Готовимся к Java 9. Обзор самых интересных улучшений
    0

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

  • Готовимся к Java 9. Обзор самых интересных улучшений
    0

    Думаю, не будет Collection literals. По крайней мере, не в ближайшие годы.

  • Готовимся к Java 9. Обзор самых интересных улучшений
    0

    А если мутабельный список, потокобезопасный он или нет? А добавление в начало или в середину дешёвое или нет? Реализаций списков много. А с Set и Map ещё хуже. Сохраняет ли порядок, сортирует ли ключи. Например, в JavaScript объекты сохраняют порядок вставки, а это дополнительные ненужные накладные расходы в 99% случаев. Сериализуемость, потокобезопасность. Можно ли в Java 9 сериализовать List.of(x) и десериализовать его потом в Java 8, получив аналог Collections.singletonList(x)? Много, много интересных вопросов влечёт такая фича. Это всё на тему того, почему 10 лет назад не сделали.


    ArrayList.of(1,2,3) обсуждался, но он перекрывает List.of(1,2,3), а это нехорошо, когда один статический метод перекрывает другой, меняя семантику. Опять же привет старому поспешному дизайнерскому решению, что статический метод можно вызывать, используя подкласс в качестве квалификатора. Напишите вы class MySuperList extends ArrayList implements List, и что будет значить MySuperList.of(1,2,3)?

  • Используйте Stream API проще (или не используйте вообще)
    0

    forEach изящнее выглядит со ссылкой на метод. Кроме того может быть несколько быстрее, потому что не создаётся итератор.


    Я до сих пор не понимаю, почему разработчики Java решили добавить Stream API непосредственно в интерфейс коллекция?

    Ну вот любят люди всё такое fluent-fluent. Все вон трещат, чтобы им прямо в коллекцию добавили map или filter. Написать свой утилитный класс и вызывать статические методы религия не позволяет. Stream.from(veryLongCallProducingACollection).many().stream().operations() тоже смотрится не очень.


    Вообще с точки зрения разработчиков Java, стримы более базовая вещь, чем коллекции. От коллекций по факту зависит только класс Collectors, который утилитный. Остальные стримы от коллекций не зависят.

  • Готовимся к Java 9. Обзор самых интересных улучшений
    0

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

  • Готовимся к Java 9. Обзор самых интересных улучшений
    0

    Читайте дискуссии на эту тему в core-libs-dev. Много что мешало.

  • Готовимся к Java 9. Обзор самых интересных улучшений
    0

    А потом программисты начнут использовать эти два метода, а пользователи начнут жаловаться, почему это у них новая версия программы падает с NoSuchMethodError. А программисты им такие, да, теперь вам каждую неделю надо обновлять JRE, чтобы пользоваться нашим софтом.

  • Используйте Stream API проще (или не используйте вообще)
    +1

    Насчёт IDE не заменяет голову, кстати, пример. IDEA предупредит, если вы напишете Arrays.asList(array).stream(). Но если у вас сложный внешний стрим и в нём встретится .map(Arrays::asList).flatMap(List::stream) вместо простого .flatMap(Arrays::stream), то тут уже не предупредит. Или про filter().findFirst().isPresent() скажет, но если вы промежуточный Optional присвоите в переменную и используете её только для isPresent, то уже увы. Может когда-нибудь и эти случаи покроем, но не стоит надеяться, что IDE вам подскажет всегда.

  • Используйте Stream API проще (или не используйте вообще)
    +4

    Готово


  • Используйте Stream API проще (или не используйте вообще)
    0

    Собственно да. С помощью стандартного Stream API вроде красиво не решить. Моя библиотека StreamEx позволяет легко сделать такой коллектор:


    static <T> Collector<T, ?, Boolean> anyMatchOrEmpty(Predicate<T> predicate) {
        return MoreCollectors.pairing(
              MoreCollectors.filtering(predicate, MoreCollectors.first()), 
              MoreCollectors.first(),
              (filtered, nonFiltered) -> filtered.isPresent() || !nonFiltered.isPresent());
    }

    С обычным стримом он не будет короткозамкнут, но если источник обернуть в StreamEx (или если источник сразу возвращает StreamEx), то будет:


    return StreamEx.of(someStream(...)).collect(anyMatchOrEmpty(condition));
  • Используйте Stream API проще (или не используйте вообще)
    0

    Однако он не будет короткозамкнутым, потому что в стандартном Stream API не бывает короткозамкнутых коллекторов (у меня в StreamEx они есть)