[java] Почему я не люблю Java

Werdna

Только один аспект затрону, никак не другие темы — высокое потребление ресурсов, общая тормознутость и пр.
Кратко: слишком-многабукв-многафайлов.
Программы на Java — это 3-4-5 уровней каталогов, причем часто — 1 файл в самом нижнем каталоге. Большая часть кода занимает декларации чего-либо, вызовы-перевызовы, абстрактные классы и т.д.
В итоге если очень хочется понять, что и как работает, то начинается хождение по многим файлам сразу. Кропотливо, ты идёшь в функцию, из которой что-то должно делаться. Потом ты понимаешь, что там одна строчка, которая на самом деле делает что-то другое. Ты идёшь в другой файл, и видишь там, что это от чего-то там наследуется, идёшь в третье место... И так, шаг за шагом ты распутываешь клубок.
Возможно, тебе помогает IDE, так как там есть инструменты быстро по файлам переключаться.
В других языках — всё не так запущено. Конечно, вся эта фигня тем больше пожирает исходники, чем больше неуместного ООП в проекте. Но Java — тут без вариантов.
Не бывает так, что простая программа и 3 файла в каталоге src.
На Питоне — бывает. На PHP — бывает. На C++ тоже бывает.
На Java — всегда будет на одну строчку смысла строчек двадцать белиберды.

SergeRRRRRR

тсс, не говорите ему про рефлексию.

yroslavasako

юзай скалу.

6yrop

чтобы тормоза еще раньше были: при компиляции

yroslavasako

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

luna89

Я бы добавил, что java-опухоль постоянно пытается дать метастазы в другие, еще здоровые платформы. По моим ощущениям, PHP уже заражен безнадежно, под него уже наклепали джаваподобных фреймворков по типу такого и среднестатистический пхпшник уже боится самостоятельно, без фреймворка, какой-то код написать. Javascript пока держится, например java-подобный фреймворк angular был отринут javascript-сообществом.
Какую-то попытку анализа ситуации я встречал в эссе Java Shop Politics, там java рассматривается в контексте организационной структуры компаний, которые ее применяют.

yroslavasako

Я, конечно, не веб программист, но хабре регулярно пишут про angular. Как-то он не похож на сдохший проект. По поводу опухоли. Там scala.js зреет. Сам компилятор уже вылез из беты, скоро бету перешагнёт инфраструктура. Тогда среднестатистический пользователь узнает, что такое 20 метров ява скрипта на страничке.

6yrop

Тогда среднестатистический пользователь узнает, что такое 20 метров ява скрипта на страничке.
Я что-то пропустил, на скале пишут для среднестатистического пользователя?

6yrop

фреймворк angular был отринут javascript-сообществом.
У js-сообщества это перманентное состояние — отторгать очередной фремворк:

luna89

Я что-то пропустил, на скале пишут для среднестатистического пользователя?
Довольно активно пишут, даже в Москве. Обычно это происходит так - пара-тройка java программистов решают усилить свое резюме знанием скалы, ставят scala-плагин к идее, и пишут такой же код как раньше, только синтаксис немного другой, и не надо нажимать кнопку generate getters and setters.

yroslavasako

Я что-то пропустил, на скале пишут для среднестатистического пользователя?
Ну там есть django подобный server side. Из-за него тег scala на stackoveflow перманентно заполнен тупыми вопросами. Веб программистов на скале порядочно, есть подозрение что даже больше всех остальных. А теперь у них случился тот же загон, что и у node.js - давайте на одном языке писать как для server side, так и для client side.

schipuchka1

На Питоне — бывает. На PHP — бывает. На C++ тоже бывает.
На Java — всегда будет на одну строчку смысла строчек двадцать белиберды.
Это просто сейчас слишком много языков называют языками общего назначения, а это не так.
Вот питон, к примеру - хороший язык для написания write only скриптов. Они будут занимать несколько файлов и в них не будет ничего лишнего. Так как проект маленький, то автор будет помнить как оно всё работает и проблем не будет. Если же в проекте нужно сделать больше одного уровня сложности и в особенности, если разрабатывает несколько человек, то сразу становится всё плохо: питон поддерживает только методологию "хуяк-хуяк и в продакшн". Программа начинает сыпаться в произвольном месте с ни о чём не говорящим исключением, какая-нибудь библиотека после обновления может ожидать получать вместо содержимого файла ссылку на него или делать половину работы в зависимости от погоды на марсе и других подключенных модулей, через месяц после работы на продакшне программа может упасть с ошибкой компиляции.
Джава - другая, да. Она не подходит для скриптов и заставляет тебя писать поддерживаемый код: сразу думать как ты хочешь обрабатывать ошибки, поддерживает его связность и заставляет тебя думать о куче других вещей. Зато более сложные проекты работают без особых проблем.

6yrop

А теперь у них случился тот же загон, что и у node.js - давайте на одном языке писать как для server side, так и для client side.
Это не загон, это так же естественно, как дышать.

6yrop

Если же в проекте нужно сделать больше одного уровня сложности
:grin:

luna89

Программа начинает сыпаться в произвольном месте с ни о чём не говорящим исключением, какая-нибудь библиотека после обновления может ожидать получать вместо содержимого файла ссылку на него или делать половину работы в зависимости от погоды на марсе и других подключенных модулей, через месяц после работы на продакшне программа может упасть с ошибкой компиляции.
Самые загадочные падения в рантайме я встречал у джавы как раз. Например, бывает забавная ошибка X cannot be cast to X, вот результаты в гугле по этой проблеме. Джава очень сильно предрасположена к стохастическим ошибкам, которые воспроизводятся в зависимости от фазы луны. На это есть ряд причин, основная - инфраструктура написана бесноватыми индусами. Джава-программисты любят рассказывать про секретные высоконагруженные NDA проекты, но используемые инструменты стесняются комментировать. Например, есть такой скачиватель зависимостей Maven, есть проблема diamond зависимостей - либа A зависит от C версии 1.1, а B - от C версии 1.2. Maven решает эту проблему так, что скачивает и добавляет обе версии в classpath, а какая версия будет подхвачена, решается уже в рантайме, в зависимости от порядка итерации по файлам в файловой системе.
Помню, дедлайн, надо что-то делать, а у меня вылетает этот странный ClassCastException. У всех работает, а у меня нет. Я пересобрал проект, переустановил джаву пару раз, не работает. Думал уже переустановить операционку, но тут что-то щелкнуло в компьютере, и у меня опять все заработало. Тут важно отметить, что никаких отладочных инструментов нет, джава-приложение - монструозный непрозрачный ком, который живет своей богатой внутренней жизнью.
Еще одна причина стохастических багов - нездоровое увлечение concurrency, которую пихают куда не надо. Там, где в питоне будет набор легковесных скриптов, запускаемых хоть из веб-сервера, хоть из крона, хоть из очереди сообщений, в джаве будет монолитная программа, с глобальными переменными замаскированными в каких-то мрачных depency injection контейнерах. Набор скриптов хорош тем, что у него нет какого-то shared state. Кроме того, отдельный скрипт легко переписать с питона на что-то другое, это настоящая модульность. Приложения написанные на скриптах зачастую можно отладить вообще через strace. Иногда я отлаживал незнакомые программы таким способом - заменял какой-то скрипт на обертку, которая логировала аргументы и передавала их в оборачиваемый скрипт, после этого можно было легко понять, с правильными ли агрументами вызывается скрипт, и подобрать нужные аргументы, вызывая скрипт просто из командой строки. Джаве такой уровень интроспекции и не снился.

Hastya

Только один аспект затрону, никак не другие темы — высокое потребление ресурсов, общая тормознутость и пр.
Отличный тред. Made my day.
:grin: :grin: :grin:

Barbie29

ООП угробит проганье, потому что их всемером не удержишь

schipuchka1

Тут важно отметить, что никаких отладочных инструментов нет, джава-приложение - монструозный непрозрачный ком, который живет своей богатой внутренней жизнью.
:shocked:
А можешь рассказать немного о своих проектах? Лично я привык отлаживать её прям в IDE, если надо вообще подключаясь к удалённой машине с подхватом кода, очевидно.

schipuchka1

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

Marinavo_0507

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

danilov

> Я бы добавил, что java-опухоль постоянно пытается дать метастазы в другие, еще здоровые платформы. По моим ощущениям, PHP уже заражен безнадежно
Звучит убедительно. Пошёл учить таблицы ==, === и isNone для разных типов

psm-home

Давай разберем твою жаба-психотравму по пунктам:
Например, бывает забавная ошибка X cannot be cast to X, вот результаты в гугле по этой проблеме.

Ну да, один и тот же класс C, загруженный разными classloaders это 2 разных класса. Букварная ошибка, как жаль что ты работал жаба погромистом и не прочел букварь. Плохая жаба, плохая.
На это есть ряд причин, основная - инфраструктура написана бесноватыми индусами.

Инфраструктура - это в первую очередь JVM, state of art штука, включающая в себя отличный JIT компилятор, весьма быстрая и надежная (и прожорливая по памяти). До тех индусов, что её писали, большинству погромистов на node.js как до Луны раком примерно.
Например, есть такой скачиватель зависимостей Maven, есть проблема diamond зависимостей - либа A зависит от C версии 1.1, а B - от C версии 1.2. Maven решает эту проблему так, что скачивает и добавляет обе версии в classpath, а какая версия будет подхвачена, решается уже в рантайме, в зависимости от порядка итерации по файлам в файловой системе.
Помню, дедлайн, надо что-то делать, а у меня вылетает этот странный ClassCastException. У всех работает, а у меня нет.

Опять злые дядьки нагадили тебе в шаровары, заставили использовать на твоем проекте нехороший maven вместо прекрасного make или чего там. Кстати, почему ты все не переделал там, как нужно, по правильному, а вместо этого пассивно страдал?
Да, мавеном, как любым инструментом, надо уметь пользоваться, знать про mvn depency:analyze / mvn depency:tree / maven-enforcer-plugin. Ты не знал, бяда. :(
Джаве такой уровень интроспекции и не снился.

Все нормально в жабе с интроспекцией, начиная с jstack/jmap и далее везде, strace делать кстати тоже никто не запрещает.
В общем, сорри, я и сам люблю жабу поругать, но уровень критики. :( Я думал, намного лучше это все будет.

luna89

А можешь рассказать немного о своих проектах? Лично я привык отлаживать её прям в IDE, если надо вообще подключаясь к удалённой машине с подхватом кода, очевидно.
Во-первых, к продакшен серверу не подключишься. Но допустим, проблема воспроизводится у тебя локально на машине. Я конкретный баг описал, как тебе в его отладке поможет дебаггер? Там проблема явно в каком-то коде работы с класслоадерами, или какой-то класс грузится не из того джара, что ты увидишь в дебаггере?
Кстати, в джаве если у тебя есть какой-то третьесторонний джар, то в него непонятно как вообще вставить отладочную печать. В питоне внешняя библиотека - это просто текстовые файлы, без всяких zip-архивов, открыл в тектовом редакторе и навставлял принтов.
Ну и конечно дебаггер - это вообще неудобно. Например, у тебя есть код какого-то обхода дерева (пример жизненный, потому что например класслоадеры в джаве образуют дерево), как выглядит твоя работа в дебаггере? Как я себе представляю, надо сидеть много раз жать Step Over / Step Into, все время рискуя промахнуться и начинать все заново.

luna89

Букварная ошибка, как жаль что ты работал жаба погромистом и не прочел букварь. Плохая жаба, плохая.
Да, я к сожалению очень плохой программист, и мне трудно даже информацию из букваря усвоить. Поэтому я выбираю подходящую мне платформу - javascript или например PHP. Там написал, и сразу все заработало, без всяких класслоадеров. Пусть каждый занимается своим делом - я буду писать программы под простые быдлоплатформы, а джаваархитекторы будут писать сложные программы с многочисленными полезными класслоадерами.
Кстати, почему ты все не переделал там, как нужно, по правильному, а вместо этого пассивно страдал?
По-правильному, нужно было бы джаву вообще удалить, но это было бы слишком радикально.

schipuchka1

Там проблема явно в каком-то коде работы с класслоадерами, или какой-то класс грузится не из того джара, что ты увидишь в дебаггере?
Инициализация класса тоже дебаггером подхватывается на отлично.
Кстати, в джаве если у тебя есть какой-то третьесторонний джар, то в него непонятно как вообще вставить отладочную печать. В питоне внешняя библиотека - это просто текстовые файлы, без всяких zip-архивов, открыл в тектовом редакторе и навставлял принтов.
Ага, совсем забыл про любимую дисциплину питон погромистов: профиксить то, как работает внешняя библиотека и сделать этим подарок при её обновлении другой команде.
Во-первых ты можешь подключить исходники почти ко всем внешним библиотекам и смотреть что и где выполняется по ним (мы же о дебаге говорим, нет?)
Во-вторых ты можешь восстановить исходный код даже если нет исходников.
В-третьих ты в каждый момент времени видишь состояние всех переменных при дебаге даже без исходников.
Ну и конечно дебаггер - это вообще неудобно. Например, у тебя есть код какого-то обхода дерева (пример жизненный, потому что например класслоадеры в джаве образуют дерево), как выглядит твоя работа в дебаггере? Как я себе представляю, надо сидеть много раз жать Step Over / Step Into, все время рискуя промахнуться и начинать все заново.
Для ленивых есть брекпоинты

evgen5555

Все нормально в жабе с интроспекцией, начиная с jstack/jmap и далее везде,
Видел хоть раз кучу NPE вместо стектрейсов в логе jstack? :)

schipuchka1

По-правильному, нужно было бы джаву вообще удалить, но это было бы слишком радикально.
что, не хотелось backend код на js писать?

schipuchka1

Кстати пользуясь случаем вопрос: питон\js погромисты, вы какой IDE пользуетесь?

Dasar

питон\js погромисты, вы какой IDE пользуетесь?
VisualStudio ) Но я не настоящий сварщик, и использую python и js - фрагментарно.

luna89

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

Dasar

Брейкпоинты - это инструмент который не скриптуется
На основе чего сделан такой вывод?

luna89

вы какой IDE пользуетесь?
Для джаваскрипта использую GNU Screen, vim c плагином vim-slime, ctags и eslint

luna89

На основе чего сделан такой вывод?
Мб под другие платформы скриптуется, в джаве, если использовать Eclipse/Idea, то нет

Dasar

jdb скриптуется

luna89

jdb скриптуется
Это просто же cli тулза, без интеграции с текстовым редактором?
Впрочем, все равно, отладочные принты удобнее чем какое-то скриптование дебаггера

fufa58

в джаве, если использовать Eclipse/Idea, то нет
conditional breakpoints же :o
их вообще можно понаставить в библиотеки, напихать в них кода с отладочной печатью, и аргумент про текстовые исходники библиотек питона пропадает.

Werdna

Брейкпоинты - это инструмент который не скриптуется, поэтому в нем приходится совершать нудную тупую работу - ходить кнопочками по дереву вызовов.
Так макаки же сидят брэкпоинтят, а потом "у меня всё работает" или какой костыль вписывают.
Они не понимают, что можно на 10 машинах поставить скриптик и собирать нужные данные. И что ты продакшен не можешь брэкпоинтить чаще всего.

schipuchka1

И что ты делаешь, если нужно поменять сигнатуру метода? Какие есть возможности стат проверки кода и рефакторинга?

schipuchka1

А накатывать непонятно как работающий скрипт напродакшн можешь?

stm5872449

Джава - другая, да. Она не подходит для скриптов и заставляет тебя писать поддерживаемый код: сразу думать как ты хочешь обрабатывать ошибки, поддерживает его связность и заставляет тебя думать о куче других вещей. Зато более сложные проекты работают без особых проблем.
Ну конечно. По факту люди вставляют try ... catch {} в произвольных местах, чтобы их не отвлекали от Абстрактных Фабрик Синглтонов. :p
В питоне внешняя библиотека - это просто текстовые файлы, без всяких zip-архивов, открыл в тектовом редакторе и навставлял принтов.
Если это конечно не сишное расширение, тогда соси лапу. ;)

danilov

Я бы весь тред переименовал в "К - Компетентность". Не, серьёзно. У меня нехило бомбит. И даже не из-за нападок на жаву, здесь, в общем-то, так принято, и надо признать, аргументы обычно весомые. Но конкретно в этом треде творится какой-то икспердный трололо. Во что превратился этот раздел? Где программисты-то? Вам самим не стыдно писать-то такую херню?

luna89

И что ты делаешь, если нужно поменять сигнатуру метода?
Меняю сигнатуру и прохожусь по всем местам вызова.
Какие есть возможности стат проверки кода и рефакторинга?
Практически никаких

YUAL

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

Garryss

запустил strace -f на джава апликуху, работающую на холостом ходу без нагрузки. так эта сволочь мне так забила мне узенький канал до сервера, что мне пришлось ждать пока ssh-сервер на том конце не сдетектирует что сессия накрылась и не убьёт strace.
Потому что нужно делать strace -f | grep -v futex. JVM — вещь сильно многотредовая, а синхронизация обеспечивается через futex(2).
Тред сводится к "мне не нравятся задачи, которые решают джавой, но зато нравятся задачи, которые решают питоном и пыхпыхом".

schipuchka1

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

zya369

а если твоя IDE в одном месте Class.method подцепит из одного jar-а, а вдругом - из другого - она сообразит, что это на самом деле один и тот же Class только подцелпенный из разных мест?
или ты спокойно отрефакторишь а потом будешь ловить точно так же в продакшне?

sania1974

питон программисты, вы какой IDE пользуетесь?

pycharm

schipuchka1

Как ты это себе представляешь? Если нет актуальной версии кода, то покажет предупреждение.

zya369

яхз как
если прога на джаве может сделать это в проде, то почему IDE, которая тоже наверняка на джаве, не может поступить так же?

schipuchka1

Если у тебя есть несколько версий одной библиотеки, то подгрузится только одна. Если ты грузишь одну библиотеку двумя класслоадерами (зачем?), то ты получишь то, как настроишь.
Кстати картинка в тему сегодняшняя:

yroslavasako

Да нифига это не загадочное падение, человек просто документацию не читал. Я когда увидел строчку гугла, первым делом подумал, а classloader у них одинаковый? Потом открываю stackoverflow - так и есть. Не найти для ява дебагера - это пять. Там даже ретродебаг есть.
Но вообще, автор подтвердил мой тезис, один язык для всех случаев жизни - не очень. Для маленьких скриптов нужен маленький скриптовый язык. А для параллельности - уже нормальная виртуальная машина, python, php, javascript - и прочие скриптоязыки в параллельность не умеют.

yroslavasako

Если ты грузишь одну библиотеку двумя класслоадерами (зачем?)
Если автор не читал документацию, то он скорее всего даже не знает, что такое класслодер. Рассчитывал на какую-то "магию".

yroslavasako

И что ты делаешь, если нужно поменять сигнатуру метода? Какие есть возможности стат проверки кода и рефакторинга?
unit тесты. Они буквально необходимы как воздух для языков без типизации.

schipuchka1

Ну добиться этого не так-то легко

Hastya

Во что превратился этот раздел? Где программисты-то? Вам самим не стыдно писать-то такую херню?
Ты не умеешь. Пиши так: PHP - говно! Это даже не объектно-ориентированный язык!

YUAL

strace -f | grep -v futex
ещё раз обращу внимание, что сервер работал без нагрузки.
Вот например приложение на go (умный прокси с авторизацией).
 strace -f -p 10885 2>&1 | wc -l & sleep 10; killall strace
[1] 8912
15

А вот его предыдущая версия на джаве почти полностью с той же функциональностью.
 
  strace -f -p 1816 2>&1 | wc -l & sleep 10; killall strace
[1] 6249
19266

Ну или вот с твоим грепом.
 trace -f -p 1816 2>&1 | grep -v futex |wc -l & sleep 10; killall strace
[1] 8999
10029

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

kill-still

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

kill-still

надо уметь пользоваться, знать про mvn depency:analyze / mvn depency:tree / maven-enforcer-plugin. Ты не знал, бяда.
Там ещё есть настройка политики (например брать всегда старший артефакт, или просто вставать раком (бросать ошибку)).

Werdna

Да, мавеном, как любым инструментом, надо уметь пользоваться, знать про mvn depency:analyze / mvn depency:tree / maven-enforcer-plugin. Ты не знал, бяда

Особенно убивает вот это — порог вхождения.
Если ты не знаешь 100500 каких-то говняных штук, типа что можно где-то какую-то галку поставить и оно ВНЕЗАПНО начинает работать.
В итоге знание Java == на 10% знание Java и на 90% умение тыкать нужные штуки в окошках IDE и прочих дебаггерах.
В питоне ты изучаешь язык и сразу начинаешь писать. В том редакторе, в котором тебе удобно. Сам под себя начинаешь подбирать тулзы и IDE какие тебе нравятся. Тебе не надо погружаться в правила неведомые и выбирать монастырь, в который со своим уставом не ходят.

schipuchka1

Особенно убивает вот это — порог вхождения.
Если ты не знаешь 100500 каких-то говняных штук, типа что можно где-то какую-то галку поставить и оно ВНЕЗАПНО начинает работать.
В итоге знание Java == на 10% знание Java и на 90% умение тыкать нужные штуки в окошках IDE и прочих дебаггерах.
В питоне ты изучаешь язык и сразу начинаешь писать. В том редакторе, в котором тебе удобно. Сам под себя начинаешь подбирать тулзы и IDE какие тебе нравятся. Тебе не надо погружаться в правила неведомые и выбирать монастырь, в который со своим уставом не ходят.
Кто ж тебя бедного заставляет мавеном пользоваться? Пиши на Java в vi, потом собирай и выполняй из командной строки, все нужные зависимости скачай в папочку.
Если же нужен инструмент, чтобы облегчить это, то уж потрудись понимать, как он работает.

agent007new

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

Werdna

Кто ж тебя бедного заставляет мавеном пользоваться? Пиши на Java в vi, потом собирай и выполняй из командной строки, все нужные зависимости скачай в папочку.
К сожалению, это НЕВЕРОЯТНО сложно.
Написать самый простой Hello-World без IDE — это очень и очень много всего надо заботать. Если подключить ещё либу, то ещё часа 2-3 убьёшь.
Собственно об этом и речь, Java сама по себе на 90% состоит из этого всего говноинструментария, без которого ты вообще никак не сможешь начать работать.

luna89

Написать самый простой Hello-World без IDE — это очень и очень много всего надо заботать. Если подключить ещё либу, то ещё часа 2-3 убьёшь.
Собственно об этом и речь, Java сама по себе на 90% состоит из этого всего говноинструментария, без которого ты вообще никак не сможешь начать работать.
Я бы уточнил, что как раз говноиструментарием можно не пользоваться, скомипилировать и запустить из командной строки не сложнее чем в C++. В принципе, если не пользоваться говноинструментарием, можно что-то работающее написать. Но кто это понимает, тот джавой вообще не станет пользоваться.

schipuchka1

Написать самый простой Hello-World без IDE — это очень и очень много всего надо заботать. Если подключить ещё либу, то ещё часа 2-3 убьёшь.
:o
:~$ echo "public class HelloWorld { public static void main(String[] args) {System.out.println(\"Hello world, \");}}" > HelloWorld.java
:~$ javac HelloWorld.java
:~$ java HelloWorld
Hello world,

kill-still

Написать самый простой Hello-World без IDE — это очень и очень много всего надо заботать. Если подключить ещё либу, то ещё часа 2-3 убьёшь.
Собственно об этом и речь, Java сама по себе на 90% состоит из этого всего говноинструментария, без которого ты вообще никак не сможешь начать работать.
Не гони херню. Даже наши ПХПшники осилили весь стек технологий за месяц, не говоря уже о Hello-World.

yroslavasako

Особенно убивает вот это — порог вхождения.
Если ты не знаешь 100500 каких-то говняных штук, типа что можно где-то какую-то галку поставить и оно ВНЕЗАПНО начинает работать.
Прогай на си. С плюсами и бустом. И юзай make файлы с кастомными скриптами и автохелом. Там порог вхождения ещё больше.

yroslavasako

Видимо, победила толерантность.
Когда-то программистов PHP за людей не считали просто.

Bibi

я просто оставлю это здесь
http://ferd.ca/the-little-printf.html

luna89

В итоге знание Java == на 10% знание Java и на 90% умение тыкать нужные штуки в окошках IDE и прочих дебаггерах.
Я кстати до поры до времени думал, что тыкание кнопок в визардах осталось в 90-x, типа как UML или что-то такое. Но знакомясь со скалой, я с удивлением обнаружил, что официальные туториалы предлагают скачать визард для генерации проекта. Инсталлер визарда весит 500Мб, что намекает на легковесность потенциальных приложений.

luna89

И юзай make файлы
В джава мире до сих пор не смогли повторить make. Нет стандартного способа решить задачу: для каждого файла *.foo сгенерить файл *.bar с помощью утилиты baz, причем сделать это только для изменившихся файлов.

yroslavasako

В джава мире до сих пор не смогли повторить make
А зачем повторять make, если он уже есть?

NataNata

у меня в свое время пригорело от type erasure и отсутствия yield-ов, хотя бы в варианте c#
кстати, а сейчас mvn все еще используется? есть же gradle, удобно и настраиваемо

Papazyan

Не гони херню. Даже наши ПХПшники осилили весь стек технологий за месяц, не говоря уже о Hello-World.
Так это ты испортил кинопоиск.

kill-still

Наш релиз был постепенным и успешным. Мы на старом сайте зафигачили плашку "перейти на новый сайт". Как половина пользователей переползла, поменяли DNS, и уже на новом сайте запилили плашку "перейти на старую версию".

Whoman-in-white

Джава - другая, да. Она не подходит для скриптов и заставляет тебя писать поддерживаемый код: сразу думать как ты хочешь обрабатывать ошибки, поддерживает его связность и заставляет тебя думать о куче других вещей. Зато более сложные проекты работают без особых проблем.
Зачем вообще нужна джава, если есть с++ с неплохой поддержкой кроссплатформенности в виде с++11 и буста, плюс с заведомо бОльшей скоростью работы программы и с бОльшими возможностями?

smit1

и с бОльшими возможностями?
В том числе выстрелить себе и другим в ногу.

Whoman-in-white

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

pilot

Зачем вообще нужна джава
Так ведь автор жавы говорил что она нужна для посредственного программиста. Соответственно есть защита от выстрелов в ногу и прочие плюшки облегчающие жизнь этому ушлепку.

schipuchka1

Зачем вообще нужна джава, если есть с++ с неплохой поддержкой кроссплатформенности в виде с++11 и буста, плюс с заведомо бОльшей скоростью работы программы и с бОльшими возможностями?
не всё так однозначно. Повторяя классические доводы:
1. Java имеет значительно меньшую ошибки - легче найти, сложнее сделать, выстрелить в ногу сложно - надёжность или хотя бы предсказуемость.
2. Ты в любом случае можешь хотеть запустить программу в песочнице
3. Про быстродействие:
3.1. Разница отнюдь не на порядок
3.2. Процессорное время не так часто уже важно, важнее другие задержки
3.3. Java компилятор знает о коде больше, так что зачастую может его оптимизировать для процессора лучше и Java будет работать быстрее
4. Про сборщик мусора - в C++ уже умеют эффективно дефрагментировать память?

apl13

4. Про сборщик мусора - в C++ уже умеют эффективно дефрагментировать память?
В плюсах тоже может быть сборщик, или ты о чем?

schipuchka1

В плюсах тоже может быть сборщик, или ты о чем?
я знаю, что он там может быть, просто в Java уже давно не просто сборщик мусора :). GC в Java занимается ещё такой хорошей вещью, как дефрагментация памяти. Т.е. если ты выделишь овер 9000 объектов (размера Х) в C++, а потом освободишь каждый второй, то ты в любом случае забьёшь всю память и найти место на объект размера 2Х не получится, хотя у тебя куча свободного места после удаления половины объектов.
В Java же память будет дефрагментирована и ты сможешь создавать объекты любого размера на освободившейся памяти. (Это кстати главная причина почему Java жрёт много памяти - дефрагментация требует доп памяти.) GC в Java очень эффективно обслуживает обычные случаи загрязнения и фрагментации памяти.

schipuchka1

Ну и да, вся сущность С++ препятствует эффективной работе GC: http://www.stroustrup.com/C++11FAQ.html#gc-abi

danilov

Да вроде не всё так радужно. Дефрагментировать без stw научились относительно недавно, только в G1. И это вовсе не основная причина, почему она жрёт много памяти. Реально GC хорошо работает только в предположении гипотезы о жизни объектов, что, во-первых, не всегда так, а во-вторых, это подстраивается только в рантайме и не очень быстро, т.е. первые сборки будут очень неэффективными. Совсем без фризов умеет только azule (из мне известных), но за счёт read-барьеров, что аффектит производительность. Возможно, что-то есть у RT, но я хз. Кароче, неочевидно, что это один огромный плюс

schipuchka1

Ну зависит от способа использования конечно. Java оптимизируется под долгое выполнение программы, тут и компиляция после прогрева и настройка остальных частей. Идеала нет и ты в любом случае меняешь производительность на надежность и оптимальность работы с другими ресурсами (ака память).
Если тебе нудна производительность ты, кстати, можешь настроить другой gc, несжимающий.
Так что есть свои особенности, но ИМХО плюс внушительный.
А что, по твоему мнению, главная причина прожорливости по памяти?

luna89

Сейчас написал две одинаковые программы на тест gc, одну на ноде другую на джаве:

vagrant-ubuntu-trusty-64:~/gctest$ cat Test.js
var a = [];
var i;
for(i = 0; i < 4000; i++){
a.push(i.toString());
}
for(i = 0; i < 40000000; i++){
a.push(i.toString());
a.shift();
}
vagrant-ubuntu-trusty-64:~/gctest$ cat Test.java
import java.util.ArrayList;
public class Test {
public static void main(String[] args){
ArrayList<String> a = new ArrayList<String>();
int i;
for(i = 0; i < 4000; i++){
a.add(String.valueOf(i));
}
for(i = 0; i < 40000000;i++){
a.add(String.valueOf(i));
a.remove(0);
}
}
}
vagrant-ubuntu-trusty-64:~/gctest$ javac Test.java && time java Test

real 0m36.957s
user 0m36.193s
sys 0m0.476s
vagrant-ubuntu-trusty-64:~/gctest$ time node Test.js

real 0m6.157s
user 0m6.127s
sys 0m0.236s
vagrant-ubuntu-trusty-64:~/gctest$

danilov

Отсутствие value-типов, отсутствие аллокации на стеке (частично должно компенсироваться escape-анализом, насколько реально - хз), ну, и принцип работы самого сборщика. CMS-у для комфортной работы нужно вдвое больше памяти на OldGen, чем реально требуется программе. А вот дефрагментацию он не обеспечивает

danilov

А remove(0) это реально то же самое, что и shift()? И сколько, по-твоему занимает сама сборка?

danilov

Посмотрел. Говорят, что там список, а не массив. Давай то же самое с LinkedList

luna89

Посмотрел. Говорят, что там список, а не массив.
Где список?

danilov

Вот здесь http://javascript.ru/Array/shift
Это не так? Я js не знаю, честно говоря.

danilov

И здесь вроде также http://developer.mozilla.org/ru/docs/Web/JavaScript/Referen...
А вот на твоём примере, если в жаве сделать список, он cстановится в 5 раз быстрее, чем js

schipuchka1

remove(0)
это самое долгое что можно с arraylist сделать, так что это тест не на gc, а на сдвиг массива.

danilov

Я это понимаю, хочу до DDD ещё донести

luna89

А вот на твоём примере, если в жаве сделать список, он cстановится в 5 раз быстрее, чем js
В js нормальные массивы, структуры данных одинаковые используются

danilov

Не уверен, но даже если это так, ты ведь понимешь, что тестируешь вовсе не gc?
И я сейчас проверил не на 4000, а на 40000 и 400, время не изменилось. Это еще больше склоняет в сторону списков.
Кароче, пруф, что там массив.

schipuchka1

Отсутствие value-типов, отсутствие аллокации на стеке (частично должно компенсироваться escape-анализом, насколько реально - хз), ну, и принцип работы самого сборщика.
ну это побочки модели памяти, которая и обеспечивает эффективный gc

schipuchka1

Я это понимаю, хочу до DDD ещё донести
Ну я про то, что даже посли правки мы поймём только что списки в js сосут, т.к. тест получился не на то совсем.

luna89

что тестируешь вовсе не gc
Да, ты прав. Пишут что shift реализован специальным кодом, который меняет указатель на начало массива.

evgen5555

При этом на реальных, не игрушечных скоростях эффективный GC начинает сыпаться — и на этой стадии Java-программеры приступают к изобретению велосипедов для его объезда.

schipuchka1

Вывод то какой? Выкинуть gc, только ручная работа с памятью, только хардкор?

evgen5555

А вывод-то простой: из того кода, что нагородили на Java авторы, когда увидели как он работает на высоких нагрузках, можно выжать некое подмножество, которое почти полностью отображается в аналогичную программу на C++ :)

luna89

если в жаве сделать список, он cстановится в 5 раз быстрее, чем js
Еще одна попытка, теперь на списках:
 
vagrant-ubuntu-trusty-64:~/gctest$ cat Test.java
import java.util.LinkedList;
public class Test {
public static void main(String[] args){
LinkedList<String> a = new LinkedList<String>();
int i;
for(i = 0; i < 4000000; i++){
a.add(String.valueOf(i));
}
for(i = 0; i < 10000000;i++){
a.push(String.valueOf(i));
a.remove();
}
}
}
vagrant-ubuntu-trusty-64:~/gctest$ cat Test.js
var LinkedList = require('linkedlist');

var a = new LinkedList();

for(i = 0; i < 4000000; i++){
a.push(i.toString());
}

for(i = 0; i < 10000000; i++){
a.push(i.toString());
a.shift();
}
vagrant-ubuntu-trusty-64:~/gctest$ time node Test.js

real 0m5.120s
user 0m4.567s
sys 0m0.700s
vagrant-ubuntu-trusty-64:~/gctest$ javac Test.java && time java Test

real 0m5.969s
user 0m10.007s
sys 0m0.997s

danilov

А доказать-то ты теперь чего хочешь?

luna89

А доказать-то ты теперь чего хочешь?
Тезис: производительность java на уровне скриптов для анимации веб-страничек, с C++ смешно сравнивать.

stm5872449

Тезис: производительность java на уровне скриптов для анимации веб-страничек, с C++ смешно сравнивать.
Ну доказывай это честно, с прогревом виртуальных машин хотя бы.

danilov

А нахера ты тогда сравниваешь с js? И кто-то сравнивает разве? Блин, сюр продолжается. Я же хотел навсегда здесь замолчать

schipuchka1

Тезис: производительность java на уровне скриптов для анимации веб-страничек, с C++ смешно сравнивать.
сначала придумываем вывод, потом придумываем тест? Ну хватит уже некорректные бенчмарки плодить честное слово - если сильно постараться, после прогрева Java вообще поймёт что ни разу тебе эти числа не нужны и вырежет весь цикл нафиг.
Вот тебе бенчмарков для кучи:
http://bjpelc.wordpress.com/2015/01/10/yet-another-language...
http://blog.dhananjaynene.com/2008/07/performance-comparison...
http://benchmarksgame.alioth.debian.org/u64q/python.html
И да, не забывай пожалуйста о версии Java, а то мб у тебя ещё 4-ка

Whoman-in-white

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

schipuchka1

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

Whoman-in-white

Да, описался.
Вот такие штуки используют обычно при написании системы, работающей в реальном времени 24/7 http://en.m.wikipedia.org/wiki/Memory_pool

schipuchka1

А вывод-то простой: из того кода, что нагородили на Java авторы, когда увидели как он работает на высоких нагрузках, можно выжать некое подмножество, которое почти полностью отображается в аналогичную программу на C++ :)
ну извращенцев много разных бывает - некоторые не верят в gc и свой костыль придумывают, некоторые вон следят за размером байткода желая влезть в инлайн лимит...
А что, на других языках есть идеальное решение, которое работает при любой модели данных и на любой нагрузке? Ну и да, опять же - gc не подходит - есть другая часть достоинств, тут уж решай что важнее. Можно почитать мотивацию той же кассандры почему джава.

jakal222

Я кстати до поры до времени думал, что тыкание кнопок в визардах осталось в 90-x, типа как UML или что-то такое. Но знакомясь со скалой, я с удивлением обнаружил, что официальные туториалы предлагают скачать визард для генерации проекта. Инсталлер визарда весит 500Мб, что намекает на легковесность потенциальных приложений.
Некоторое время назад проходил курс: http://ru.coursera.org/course/progfun
Наибольшая сложность была с настройкой IDE :(
Хотел сначала Eclipse поставить на старый ноут ( linux mint 17 ), но Eclipse съел всю оперативку, так даже хром не поступал.
Поставил на мак Intellij - проблемы возникли. После начал ставить по видео-инструкции.
Оказалось, что у меня версия JDK не совпадает, курс рассчитан на более старую. Поменял и все заработало.
P.S: Курс интересный, Scala вообще огонь, но инструментарий слишком громоздкий.

Filan

Хотел сначала Eclipse поставить на старый ноут ( linux mint 17 ), но Eclipse съел всю оперативку, так даже хром не поступал.
Стесняюсь спросить, а сколько там памяти? На 2Gb вполне можно _работать_ (не просто учиться хэлоуворды писать, а именно работать - Java-Web на JSF, Eclipse RCP) даже с запущенным рядом FF с 10-20-30 вкладками и это всё на KDE 4!
P.S. Тред забавный, конечно. :-]

yroslavasako

Но знакомясь со скалой, я с удивлением обнаружил, что официальные туториалы предлагают скачать визард для генерации проекта.
Ты не путай официальные туториалы скалы с официальными туториалами typesafe. От способа распространения последних у меня перманентно рука-лицо.
Наибольшая сложность была с настройкой IDE :(
Хотел сначала Eclipse поставить на старый ноут ( linux mint 17 ), но Eclipse съел всю оперативку, так даже хром не поступал.
Поставил на мак Intellij - проблемы возникли. После начал ставить по видео-инструкции.
Оказалось, что у меня версия JDK не совпадает, курс рассчитан на более старую. Поменял и все заработало.
P.S: Курс интересный, Scala вообще огонь, но инструментарий слишком громоздкий.
Инструментария наоборот не хватает. В том что касается отладки и прочих jvm-ориентированных вещей. Потому что для скалы не выпускают специализированных тулзов. Даже консольного дебагера нет. Хочешь дебагать из консоли - ставь стандартный java дебагер и разбирайся с тем байткодом, который scala нагенерила. А все, кто могли бы написать scala-специфичные тулзы, уже давно разобрались с кодогенерацией, и им на нативных java тулзах норм.
Громоздкий инструментарий не обязателен. Достаточно консольного sbt и emacs с ensime.
Стесняюсь спросить, а сколько там памяти? На 2Gb вполне можно _работать_ (не просто учиться хэлоуворды писать, а именно работать - Java-Web на JSF, Eclipse RCP) даже с запущенным рядом FF с 10-20-30 вкладками и это всё на KDE 4!
В данный момент, на небольшой задаче ensime отжирает два гига, sbt в режиме простоя (есть ещё режим фоновой рекомпиляции) - 900 метров. Но это плата за мою любовь к удобному IDE. Если пользоваться идеей, то можно в разы меньше ужаться.

evgen5555

А что, на других языках есть идеальное решение, которое работает при любой модели данных и на любой нагрузке?
Отсутствие идеальных решений - это универсальный контраргумент практически на все случаи жизни :grin:
Просто странновато когда в аргументации использовании джавы упоминают ее производительность, а сам продукт падает каждые 10 минут на потоке в 1 гигабит- нахера, спрашивается, нужна эта производительность при вычислении пи?
Вот простота кодинга - это понятно. Производительность - при низкой стабильности - не совсем.

evgen5555

Активатор не пробовал?

yroslavasako

нахера, спрашивается, нужна эта производительность при вычислении пи?
Чтобы объяснять криворуким макакам, что это они программировать не умеют, а не джава не умеет считать. Кстати, sbcl тоже довольно производителен, что может быть для многих неожиданностью.

yroslavasako

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

Werdna

Чтобы объяснять криворуким макакам, что это они программировать не умеют, а не джава не умеет считать
Алё, вы в упор не слышите что вам говорят, дорогие адепты вашей сраной Явы!
Да не в подсчётах дело! Кроме подсчётов мир программинга упирается в 100500 вещей, и вот так-то настаёт полная жопа.
Ваша Ява не обещает вообще никакое разумное время отклика. Она не то что Real-time OS, она какой-то полный пиздец! Там запросто может проснуться ваш сраный гарбедж коллектор и на несколько минут приложение становится раком. За это время копится необработанная очередь запросов, которая затем разгребается, хотя половина клиентов уже забили ждать. И в итоге получаете вы говно на десятки минут.
Вы всё это лечите какими-то костылями, да, я уже слышал. Не хочу ещё слушать.
И таки да, в этом треде — не производительность. Я начал разговор про один аспект вашей явы — немеренное количество говнобукв, которые не несут смысловой нагрузки. 3/4 не пустых строк вашего кода — не несут полезной информации или являются дублирующими.

yroslavasako

Ваша Ява не обещает вообще никакое разумное время отклика
можно подумать любое другой VM со сборкой мусора обещает. Будь то питон, руби или пыхпых. Это известная проблема. И иногда не проблема.

danilov

Если вас тошнит, зачем вы её трахаете?
UPD. Ты, оказывается, не тролль, у тебя реально полыхает. У меня есть немножко аргументов к тому, что ты написал, но я так понял, тебя это не особо интересует.

Dasar

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

danilov

Он как раз эти вопросы не поднимает. Вообще, у меня было ощущение, что еще чуть-чуть и все в этом треде вскроются как жырные тролли, а я один здесь останусь полыхать.
Но если по порядку
> Ваша Ява не обещает вообще никакое разумное время отклика.
Именно, что не обещает. Не надо её использовать для RT-задач. Пианист, кажется, попытался, всё обосралось, а виноват оказался язык. На самом деле, можно попробовать Azul, или Javolution, но я не уверен, что оно даёт какие-то гарантии, надо изучить сначала.
> Там запросто может проснуться ваш сраный гарбедж коллектор и на несколько минут приложение становится раком.
Что ты там такое пишёшьк? У нас на 16 гигах в худшие времена фриз был 30 секунд. Мы конечно, вместо того, чтобы посмотреть, что у нас с памятью, тоже сразу сказали, что наше приложение идеально, виновата JVM.
> немеренное количество говнобукв, которые не несут смысловой нагрузки.
Да, некоторые языки более лаконичны, некоторые менее. IDE спасает, например, тем, что скрывает часть избыточной информации от пользователя. Про 3/4 он, конечно, загнул, но согласен, некоторые кострукции слишком громоздки. Странно, что в пример приводится C++, который гораздо сильнее этим страдает.

Dasar

Странно, что в пример приводится C++, который гораздо сильнее этим страдает.
Другой тип раздувания кода.
В C++ длинные методы, раздувание идет за счет кода, обрабатывающего ошибки и управляющего памятью.
В Java много классов/методов, раздувание идет за счет большого количества формальных конструкций, которые оборачивают одно другим.
При интуитивном подходе проще читается C++. Java читается, если уложить в голове суть фабрик, интерфейсов, паттернов, научиться их видеть в коде; и настроить удобную IDE.

Filan

Дополняя .
и на несколько минут приложение становится раком
Буквально вчера проходил по ПИМ-у по нашему приложению представитель регионального филиала заказчика.
Его вырванная из контекста фраза при прохождении пункта с проверкой одной из действительно не быстрых операций (поиск) звучала примерно так: «несколько минут ждал». Когда попросили замерить это время хотя бы на часах операционки с точностью до ±10с, то оказалось, что время ожидания было по его секундомеру 61.3с.
Это я к тому, что оценка по ощущениям типа «на несколько минут» может означать и менее минуты. А много это или мало можно сказать только в контексте задачи.

Marinavo_0507

ну одно дело один клиент ждёт минуту, другое дело весь сервер ждёт минуту (или даже менее минуты - всего 59 секунд)

Filan

Я не о времени, а о размытости формулировки «несколько минут», измеренных ощущениями. Когда подгорает, то и 20 секунд могут показаться минутами.

Dmitriy82

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

Alena_08_11

Обработка заняла 20 секунд
Всё правильно. Просто 20 не_подряд_идущих_секунд

yroslavasako

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

luna89

Java читается, если уложить в голове суть фабрик, интерфейсов, паттернов
Тут смешная история произошла. У нас есть тестировщик, который пишет автотесты на Selenium. Я ему помогаю иногда, пользуясь своими знаниями джавы.
Сегодня у него возникла задача - для каждого из нескольких возможных статусов написать тест, которые будет пытаться применить статус, и проверять что все сработало верно.
Как бы это выглядело в любом разумном языке (возьмем к примеру javascript)? Есть либа для юнит-тестов под названием jasmine. Там есть функция it, которая создает тест-спеку, например

it('should apply status', function(){
expect(applyStatus('STATUS_1')).toBe(true);
});

Теперь задача - для каждого возможного статуса сгенерить отдельную спеку:

['STATUS1', 'STATUS2', 'STATUS3'].forEach(function(status){
it('should apply status ' + status, function(){
expect(applyStatus(status)).toBe(true);
});
});

Теперь посмотрим, как это делается в джаве. Тестировщик показал мне эту страницу в документации по JUnit. Он все сделал по аналогии, но код не работал.
Я бегло посмотрел, на заметил никаких ошибок, и залез в код JUnit, желая посмотреть, можно ли там что-то отдебажить. Я начал с класса Parameterized и натолкнулся на запутанный код полный рефлекшена, фабрик и паттернов, вот пример:

private List<Runner> createRunnersForParameters(
Iterable<Object> allParameters, String namePattern,
ParametersRunnerFactory runnerFactory) throws Exception {
try {
List<TestWithParameters> tests = createTestsForParameters(
allParameters, namePattern);
List<Runner> runners = new ArrayList<Runner>();
for (TestWithParameters test : tests) {
runners.add(runnerFactory
.createRunnerForTestWithParameters(test));
}
return runners;
} catch (ClassCastException e) {
throw parametersMethodReturnedWrongType();
}
}

Я потратил минут десять, не смог ничего понять, и оставил коллегу ни с чем (надо было уходить срочно).
Мне кажется, этот пример отлично раскрывает суть джавы. В любом другом языке, если мне надо сделать повторяющееся действие, я пишу цикл, и все, задача решена.
Но джава смеется над моими знаниями в области программирования. Тут недостаточно уметь писать циклы, надо сидеть и для простейшей задачи изучать какой-то безумный DSL.

zya369

Но джава смеется над моими знаниями в области программирования.
ага, и виновата, конечно же, джава

schipuchka1

Блин, где вы такую жесть про gc находите про 30 секунд и больше - он же даже до G1 обычно только молодых вычищает, т.е. просто физически не на чем ему столько стоять.
5 лет назад на low latency проекте была максимум на ~100мсек за день остановка - и мы gc тюнили.
Чтобы 30 секунд получить, надо
1. Заставить gc перераспределять ВСЮ память. Т.е. так что даже в old gen места не хватает, а операционка больше не даёт.
2. Чтобы при этом часть памяти была на диске.
Ну т.е. это ситуация, когда на другом бы языке приложения уже бы умерли, да и на джаве скоро OOM выпадет.

schipuchka1

Тут недостаточно уметь писать циклы, надо сидеть и для простейшей задачи изучать какой-то безумный DSL.
А что тебе мешает цикл написать спрашивается?

schipuchka1

Именно, что не обещает. Не надо её использовать для RT-задач. Пианист, кажется, попытался, всё обосралось, а виноват оказался язык. На самом деле, можно попробовать Azul, или Javolution, но я не уверен, что оно даёт какие-то гарантии, надо изучить сначала.
Ну вообще может кстати обещать - ты при запуске можешь настроить параметры gc как то
-XX:MaxGCPauseMillis=200


Sets a target value for desired maximum pause time. The default value is 200 milliseconds. The specified value does not adapt to your heap size.

luna89

А что тебе мешает цикл написать спрашивается?
Как это сделать в рамках JUnit?
Почему в документации по JUnit вместо простого цикла предлагается вызывать код с рефлексией и паттернами?

yroslavasako

Это не больше чем пожелание.

danilov

> Как это сделать в рамках JUnit?
http://www.tutorialspoint.com/junit/junit_parameterized_test...
В методе, аннотированном @Parametrized.Parameters можешь использовать свои любимые циклы.
А в TestNG, например, можешь этот список предоставлять в виде xml-разметки

danilov

Речь про STW для FullGC. Более мелкие (сборка YoungGen, Mark and Sweep для CMS и, хз, как оно зовётся для G1) происходят чаще, и вот их длину уже можно контролировать разными параметрами. В CMS это пара десятков циферек, а в G1 решили в параметры вынести таргеты, откуда и появилось ощущение, что оно умеет. Но, во-первых, он будет только пытаться, а во-вторых, защиты от FullGC всё равно не будет. Единственный способ, не затрагивающий модификацию самого приложения - увеличить память. Это почти всегда работает

Werdna

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

yroslavasako

Что ты имеешь в виду? Что ты делаешь с явой, если она не выполняет твоих пожеланий? Демонстративно деинсталлишь jvm?

schipuchka1

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

schipuchka1

Ну на full gc нарваться сложно. Хотя если вы увеличиваете память, то я понимаю почему таки нарываетесь.

yroslavasako

Ну на full gc нарваться сложно
Я правильно понял, что ява не должна собирать мусор? Сборка мусора (полная) - нештатная ситуация? То есть никаких аптаймов в несколько месяцев?

Filan

Я правильно понял, что ява не должна собирать мусор?
Должна и собирает.
Сборка мусора (полная) - нештатная ситуация?

Штатная, но крайне нежелательна. Если нарываешься регулярно, то скорее всего пора память увеличивать или оптимизировать ПО.
То есть никаких аптаймов в несколько месяцев?

Не понял связи.

Filan


private List<Runner> createRunnersForParameters(
Iterable<Object> allParameters, String namePattern,
ParametersRunnerFactory runnerFactory) throws Exception {
try {
List<TestWithParameters> tests = createTestsForParameters(
allParameters, namePattern);
List<Runner> runners = new ArrayList<Runner>();
for (TestWithParameters test : tests) {
runners.add(runnerFactory
.createRunnerForTestWithParameters(test));
}
return runners;
} catch (ClassCastException e) {
throw parametersMethodReturnedWrongType();
}
}

Ты здесь рефлекшин нашёл?

danilov

> Хотя если вы увеличиваете память, то я понимаю почему таки нарываетесь.
И почему же?

danilov

Сборщики сейчас умеют чистить память без FullGC. Но не всегда выходит. И вот если не выходит, надо что-то делать

yroslavasako

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

yroslavasako

Сборщики сейчас умеют чистить память без FullGC.
Какой именно сборщик ты имеешь в виду?

danilov

Почитай, как устроен CMS, и всё поймёшь

danilov

Для жавы CMS и G1

danilov

Да, под FullGC здесь понимается STW сборка. Раньше была только она, но сейчас почти всегда есть возможность собрать мусор в параллель с работой приложения

yroslavasako

Но он, насколько я помню, на стандартный. В том смысле что по умолчанию используется более простой и менее требовательный Parallel GC. Видимо оверхед от сборки в фоне зашкаливает.

danilov

А еще по умолчанию память стомт 128 мб. Значит ли это, что больше низзя? Parallel GC он да, быстрый и при малых объёмах памяти работает очень быстро. Поэтому в большинстве случаев его хватает. А так все они вполне себе стандартные. К тому же, он был дефолтом в 1.5, а дальше я не помню, может и перекоючили

nikola1956

А на мой взгляд Java — лучший язык программирования для реального бизнеса, для промышленной разработки ПО. Когда проект, который используют сотни реальных пользователей, разрабатывают в течении года и более разные программисты среднего интеллектуального уровня, то простота языка, его прямолинейность и защита от ошибок (статическая типизация) имеют первостепенное значение. Поддержка со стороны IDE, которая лучше всего развита в Java-мире, тоже очень важна.
Программисту приходится читать и предельно ясно понимать код других разработчиков среднего уровня, чтобы добавить новую фичу. Удобнее всего это делать как раз при использовании Java. По этой причине, например, Scala плохо подходит для промышленной разработки. На мой взгляд, было бы лучше, чтобы вместо изобретения этого монстра, сделали Яву еще строже и прямолинейней.

yroslavasako

Что значит вместо? Каждый занимается своим делом. Одни пилят яву, другие скалу. Цели и финансирование у них отдельно. Меня вот вполне устраивает скала. Её всегда можно использовать только как яву на стероидах. К тому же скала не одинока. Из похожих проектов я могу назвать как минимум kotlin, ceylon (спасибо доброфоруму за ссылку) и ещё nemerle, но он для укрощения другого монстра создавался.
Кстати, я так и не понимаю, чем java лучше для посредственного разработчика чем тот же питон. Контролируемые исключения? Практика очень спорная, многие предлагают эту фичу выкинуть из явы целиком. Простота конструкций? Так у питона тоже.

nikola1956

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

Dasar

чем java лучше для посредственного разработчика чем тот же питон
Внешним контролем, что важно при низком понимании особенностей языка и слабом понимании особенностей поведения разрабатываемого продукта.

6yrop

C# няшнее

yroslavasako

внешний контроль - это система типиов? Ну так у java прогеров любимое развлечение - завернуть всё слишком сложное и непонятное в Object, а потом скастить. Перехватить все эксепшны и продолжить. Контроль не сильно помогает.
К тому же промышленная разработка - это про сетевое взаимодействие, а типы проверять в нём уже не получается. Однофигственно, что питон посылает и обрабатывает данные через сеть, что ява, и тот и другой не имеют контроль над типами. Только устные соглашения о протоколе. Что в нём может передаваться и что нет.

Dasar

внешний контроль - это система типиов?
Это и многое другое.
- невозможность испортить "чужие" типы
- невозможность повлиять некорректным способом на поведение "чужого" кода
- невозможность завести объекты без указания контракта объекта
- невозможность завести тип с противоречивым контрактом
и т.д.

Dasar

Недавняя статья, поднимающая схожую проблему:
 Срезаем углы: почему rails может убить ruby
Статья о том, как отсутствие средств контроля в языке приводит к тому, что одна библиотека убивает экосистему всего языка.

yroslavasako

В яве можно также сделать с помощью инструментария. Правда восторженные пользователи питона-руби, применяющие без лишней мысли monkey-patch, начнут говорить фуууу, рефлексия.

Dasar

В яве можно также сделать с помощью инструментария. [..] начнут говорить фуууу, рефлексия
С помощью рефлексии в Java такое не сделаешь.
Чтобы в Java провернуть monkey-patching необходимо быть Java-Hacker-ом 99-го уровня, что редко встречается у посредственных программистов. Да, и вообще, мало кто дорастает до такого понимания устройства Java.

yroslavasako

С помощью рефлексии в Java такое не сделаешь.
я же сказал - нужен инструментарий. ASM крайне упрощает этот процесс.

Werdna

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

Filan

Как можно разрабатывать на питоне что-то серьёзное для ынтырпрайза, если у него постоянно большие проблемы с обратной совместимостью? Впрочем это беда есть и у ruby, и у php. Бизнесу надо, чтобы код проработал и 5, и 10, и даже 20 лет. А на актуальной версии питона код для 2.x почти наверняка работать не будет. При этом java код конца 90-х вполне себе заведётся и будет работать на Java 8.

yroslavasako

Ну вон из джавы исчезает sum.misc.unsafe. Обратная совместимость рушится. А появление типов-параметров?

schipuchka1

Sun, Карл. Саму sun уже 5 лет как купили, на мисках депрекейт лет 10 висел.

yroslavasako

во втором javafx до сих пор живёт sun в названии внутренних классов.

schipuchka1

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

schipuchka1

Ну так старый живёт, а не новый делают.

luna89

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

Из-за такого подхода программисты теряют веру в свои возможности и не могут ни шагу ступить без фреймворка. Выше пользователь Ss пишет:
А в TestNG, например, можешь этот список предоставлять в виде xml-разметки

Когда мне нужно считать данные из XML, то я беру и читаю данные из XML, мне для этого не нужно, чтобы для этого была поддержка в каком-то TestNG.
В джаве разрушены возможности композиции, я не могу просто взять и использовать X и Y, мне нужно использовать X-Y-plugin.

yroslavasako

либо впритык памяти,
в смысле впритык? Сколько бы памяти не было, мусор накапливается. И всегда бывают объекты, которые доживают до старшего поколения, которое уже чистится через полный останов.

yroslavasako

Из-за такого подхода программисты теряют веру в свои возможности
А ты попробуй сначала сам написать. У тебя примерно также выйдет. Сначала будет тупо цикл. Потом ты заметишь, что распечатки теста малоинформативны и приделаешь класс. Потом тебя заколеблет создавать объекты этого класса вручную и ты сделаешь аннотацию. Вуаля. И я не теряю веру в себя от того, что пользуюсь чужими наработками. У меня достаточно опыта, чтобы понять зачем они нужны. А кто сомневается - пусть смотрит в исходники и просвещается.

schipuchka1

Old gen можно и без ful gc.
http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc...
Concurrent Mode Failure
The CMS collector uses one or more garbage collector threads that run simultaneously with the application threads with the goal of completing the collection of the tenured generation before it becomes full. As described previously, in normal operation, the CMS collector does most of its tracing and sweeping work with the application threads still running, so only brief pauses are seen by the application threads. However, if the CMS collector is unable to finish reclaiming the unreachable objects before the tenured generation fills up, or if an allocation cannot be satisfied with the available free space blocks in the tenured generation, then the application is paused and the collection is completed with all the application threads stopped. The inability to complete a collection concurrently is referred to as concurrent mode failure and indicates the need to adjust the CMS collector parameters. If a concurrent collection is interrupted by an explicit garbage collection (System.gc()) or for a garbage collection needed to provide information for diagnostic tools, then a concurrent mode interruption is reported.

6yrop

Сначала будет тупо цикл. Потом ты заметишь, что распечатки теста малоинформативны и приделаешь класс. Потом тебя заколеблет создавать объекты этого класса вручную и ты сделаешь аннотацию.
Что тут мало информативного?
 
foreach (var args in new[] {
new {expected = 1, input = 2},
new {expected = 2, input = 6},
new {expected = 3, input = 7},
new {expected = 4, input = 8},
new {expected = 5, input = 9},
}) AssertEquals(args.expected, Fibonacci.Compute(args.input));

Или вариант через индексы:
 
foreach (var args in new[] {
new[] {1, 2},
new[] {2, 6},
new[] {3, 7},
new[] {4, 8},
new[] {5, 9},
}) AssertEquals(args[0], Fibonacci.Compute(args[1]));

luna89

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

yroslavasako

Но тогда память может фрагментироваться. Что весьма вероятно.

6yrop

После первого не сработавшего ассерта выполненение остановится и другие не будут проверены. Плюс, ты можешь захотеть чтобы в итоговом отчете на каждый элемент в цикле был свой пункт.
Мой код на js это все учитывает.
Твой код переписывается почти один в один. Зачем для этого рефлекшен и анотации?
 
foreach (var status in new[] {"STATUS1", "STATUS2", "STATUS3"})
It($"should apply status {status}", () => Expect(ApplyStatus(status)).ToBe(true));

schipuchka1

Для old gen это обычно не проблема - используется несжимающий gc. Если это проблема, то нужно тюнить.

schipuchka1

А каким способом работают юнит тесты в шарпе? Если киданием исключения, то это не аналог и упадёт на первой же ошибке.
И да, за for без {} надо руки отрывать.

6yrop

это не аналог и упадёт на перво
а как там в js работает? Если там неявный this важен, то можно через аргумент лямбды его передать.
Как вариант, вызов лямбды обернуть в try и выкидывать агригирующий эксепшен.
 
И да, за for без {} надо руки отрывать.

если только в энтерпрайзной java

yroslavasako

Для old gen это обычно не проблема - используется несжимающий gc
именно поэтому память и фрагментируется. Нет сжатия - есть фрагменты.
И что значит "тюнить" - гадать на кофейной гуще без всяких гарантий? Ведь ты не имеешь доступа к управлению памяти. Ты можешь попытаться подобрать путём многочисленных запусков подходящие параметры, но ты никогда не получишь гарантий, что желательное поведение системы будет сохраняться при всех возможных сочетаниях внешних факторов

evgen5555

5 лет назад на low latency проекте была максимум на ~100мсек за день остановка
Постановка ордера занимает 15 мкс (по рассказам людей из DE Shaw, работающих с Java). 9 мкс у Getco вроде было на плюсах.
100 мс фриза это для LL конечно немало.

schipuchka1

если только в энтерпрайзной java
на почти любом языке кроме python, при любом адекватном code review

schipuchka1

За день, не за раз.

schipuchka1

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

yroslavasako

Ты знаешь, что хочешь получить. Не знаешь как. И знать не можешь.
Кстати о cms. Как объяснить jvm, что каждый день в четыре часа утра ты хочешь сделать full GC с компактированием?

YUAL

Рестартани её! Я видел как пацаны так в продакшене делали.

schipuchka1

Ты знаешь, что хочешь получить. Не знаешь как. И знать не можешь.
ты знаешь что хочешь получить от приложения.
К примеру время отклика очень важно и ты хочешь получить минимальное - тогда ты отключаешь сжатие, т.к. сжатие очевидно требует времени. Если просаживание на несколько миллисекунд не критично, то ты настраиваешь сжатие исходя из своей модели данный и throughput`а.
каждый день в четыре часа утра ты хочешь сделать full GC с компактированием?
1. Ты не хочешь делать full gc, ты хочешь просто почистить память. Это делается без full gc. Запустить можно и из приложения и извне, а вот сменить текущий gc и приказать сжать несжимающему нельзя (зато можно настроить разные gc на разные поколения).
Можешь впрочем подключить кастомный gc и извращаться как тебе хочется.

danilov

> Кстати о cms. Как объяснить jvm, что каждый день в четыре часа утра ты хочешь сделать full GC с компактированием?
Вроде гарантированно никак. Можно посоветовать. И обычно она его таки сделает. А можно извне. Кажется, jmap умеет, профилировщики тоже.

danilov

> Ты не хочешь делать full gc, ты хочешь просто почистить память.
Вопрос же про CMS. Конечно, он именно этого и хочет

6yrop

на почти любом языке кроме python, при любом адекватном code review
для C# это неадекватное ревью

schipuchka1

А что, на шарпе уже нельзя неправильный отступ сделать и устроить ад дебаггинга для коллег?

6yrop

Если это было бы плохо, Хельсберг запретил бы на уровне языка.
Я ему больше доверяю, чем доморощенным ревьюерам.

schipuchka1

устроить ад дебаггинга - это хорошо, да. Ещё стоит контроллабл квери внедрить, чтобы наверняка

yroslavasako

приказать сжать несжимающему нельзя
но ведь он сам это умеет делать. Неужели нельзя какую-нибудь подсказку ему выдать?
Если нельзя, всегда можно получить текущую заполненность oldGen и выделить массив на 80% от свободного пространства. Если не поместится целиком - gc сам возьмётся делать компактификацию. А если поместится, то и этого хватит.

6yrop

расскажи о своих страхах дебагинга
что тебя беспокоит?

schipuchka1

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

yroslavasako

то тебе безопасно (и ещё эффективней) делать перезапуск

Рестартани её! Я видел как пацаны так в продакшене делали.
Да ты провидец!

schipuchka1

А что, держать аптайм ради аптайма? У тебя он в любом случае прерывается, если ты останавливаешь все потоки.

Dasar

я же сказал - нужен инструментарий. ASM крайне упрощает этот процесс.
Afaik, Asm позволяет создать новый класс или скопировать существующий класс с изменениями, но не помогает изменить существующий класс.

yroslavasako

Да. Класс меняет инструментарий. java.lang.instrument.*

Dasar

Да. Класс меняет инструментарий. java.lang.instrument.*
Afaik, при подключении библиотеки в проект у библиотеки нет возможности использовать этот api

yroslavasako

Ну да. Простым способом это не сделать.

Dasar

Ну да. Простым способом это не сделать.
О том и речь. Что Java стабильна (не ломается подключением библиотеки или написанием пары строчек кода), а python/ruby/javascript не стабильны. Эта разница важна при необходимости использования посредственных программистов.

Filan

Ну вон из джавы исчезает sum.misc.unsafe. Обратная совместимость рушится. А появление типов-параметров?
Любой Java-разработчик ОБЯЗАН знать, что классы из пакетов sun и com.sun использовать категорически не рекомендуется.
Первое что нагуглилось с обсасыванием этой темы:
http://stackoverflow.com/questions/1834826/it-is-a-bad-pract...
http://stackoverflow.com/questions/1331762/suns-java-package...
Или ты знаешь что делаешь и готов к переписыванию кода, или не используй эти пакеты вообще.

yroslavasako

В питоне тоже есть ряд багов, которые использовать не рекомендуется. А их используют. Отсюда и несовместимость между версиями.

Filan

Это не баги, это внутреннее служебное апи Java, стабильность которого никто не гарантирует. И даже больше - официально рекомендуется не использовать это api.

yroslavasako

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

yroslavasako

кстати, фреймворки берут на себя большую часть забот пользователя, можешь оценить:

schipuchka1

Ух, какая энтерпрайзная матрёшка.
Оставить комментарий
Имя или ник:
Комментарий: