Personnel Management
IT career
Comments 1363
+59
Согласен. Метросексуальный макияж на ядро линукса был последней каплей.
Даешь суровый олдскул!!!
+2
image

А вообще, очень раздражает. Чай, посиделки, магнитики, тортики и сладости, дршечка на кухне.
+1
Когда-то бесили, но потом появился Web Storage API и мне уже пофик на них.
+3
Там даже через а было, чтобы не было путаницы с овечьими звуками.
+6
Вспомнилась старая картинка с «чем-то сильно расстроенной» овечкой
image
-6
«безобидное». Фу. Какой тогда смысл это писать?
Это ведь тоже детский сад
+95
Ох уж эти бунтари. Бунтуют, бунтуют… а потом пойдут доедать свои печеньки)
-21

Переходи на тёмную сторону. У нас есть печеньки!


Печеньки


А добро вообще разное бывает
+13

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


В R&D отдел срочно требуются Middle Mad Scientist, имеющие опыт работы с магическими кристаллами и плазменным оружием, либо желающие его получить. Гибкий график, оформление по ТК. Молодой и дружный коллектив непризнанных гениев. Белоснежный халат и курсы по злобному смеху за счёт компании.

0
-Герой,- кричали мне,- переходи на Тёмную сторону! У нас есть печеньки!
В ответ я доставал из рюкзачка бутерброд с колбасой и демонстративно поедал. Нашли чем приманивать! У Светлых со снабжением полный порядок. А тут какие-то печеньки… Cо временем я смеяться перестал. C нашей стороны всё было замечательно. Свой паёк я получал и мог на выпад Тёмных показать то рябчика, то ананас, другие деликатесы. Они предлагали печеньки. Cтранно. Нет, я сознавал, что у нас не каждый может себе позволить рябчиков с ананасами, но это только справедливо! Кто получает меньше, кто больше, но в целом все довольны, голодающих нет. И строй самый лучший, экономика процветает. А с Тёмной стороны мрак и беззаконие, и разруха, и коррупция, и военная диктатура… ужас творится! И всё-таки… у Тёмного всегда есть печеньки. Символический, но прожиточный минимум. Каждому, без исключения. Не хватает других вещей — лекарств, жилья, боеприпасов — но печеньки есть всегда. Для всех, без обмана. Это внушало уважение. И настал день, на обычный окрик «Эй, Светлый, не хочешь к нам? У нас есть печеньки!» я неожиданно для себя, но совершенно искренне ответил «хочу!» С той поры я на Тёмной стороне. Да, несладко. Да, у нас тут бывают проблемы. Зато у меня есть печеньки! Полные карманы! Светлая сволочь разбудит меня среди ночи и спросит: «Ну, и где..?» — я всегда готов их показать. Печеньки не кончатся никогда! Есть их категорически запрещено.

— Из комментариев к произведениям Давыдова Сергея
0
Призыв перехода на темную сторону работал бы намного убедительней, если бы предлагались не печеньки, а запасная печень)
0
не печеньки, а запасная печень
Как знать, может быть, печеньки — это картриджи для кластерного протеза печени?
+49
IT — не детский садик. Это место для взрослых, руководствующихся логикой и здравым смыслом.

Мне хочется считать программистов субкультурой.

Таки да или нет?
-31
На комментарий VIkrom не может быть дан ответ да или нет. Поэтому я пошутил с отсылкой к анекдоту на женскую логику. Разумеется, я уважаю женщин, но шутка основана на стереотипе.
И нет, я не блондинка. Я брюнет.
+16
Т.е. вы не видите хотя бы легкого диссонанса между взрослыми здравомыслящими людьми и субкультурой? Профессионалам не нужна субкультура, им нужен профессионализм.

К слову, я согласен с большей частью статьи.
+85
Геолог и профессия и субкультура. Курьер — профессия. Альпинист и профессия и субкультура. Продавец — профессия. Субкультура это не только панки и скинхэды, но и, например, учёные. Так понятнее моя мысль?
+2
Вопрос дискуссионный насколько применимо во всех этих примерах слово субкультура, но в контексте материала наверно нет смысла углубляться.
+15
Применимо, разумеется:

…«Субкультура может отличаться от доминирующей культуры собственной системой ценностей, языком, манерой поведения, одеждой и другими аспектами[1][2]. Различают субкультуры, формирующиеся на национальной, демографической, профессиональной, географической и других основах»…
-7

Вы путаете профессиональную деформацию и субкультуру.

+16
Одно ведь другому не противоречит и вполне сочетается. Писать скрипт, который будет знакомым девушкам из контакт-листа на 8 марта автоматически поздравления рассылать, не брить свитер и не стирать бороду — это профессиональная деформация. Обмениваться мало кому «из внешнего мира» понятными шуточками из мира ИТ — это как раз профессиональная субкультура. Ездить на сисопки каюсь, уже давно никто не ездит на сисопки :( на хакатоны, активно общаться на сайтах вроде Хабра — это как раз штуки, которые присущи определённому профессиональному кругу, и в общем-то действительно составляют субкультуру.
+4

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


Ездить на хакатоны, активно общаться на сайтах вроде Хабра

И что? С каких под посещение хакатонов и активность на Хабре стали частью профессии? Это сугубо опциональные вещи, весьма слабо влияющие на уровень вашего профессионализма.
Безусловно, среди программистов есть уйма представителей самых различных субкультур, но сама профессия — это ни разу не субкультура, поскольку вы без труда найдёте 2 программистов, у которых не будет ничего общего в плане систем ценностей, языка, манеры поведения и одежды.

+2
Это тоже мимо. Профессиональная деформация — это изменение восприятия под воздействием специфики профессии, включая шуточки.

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

поскольку вы без труда найдёте 2 программистов

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

Дааа лааадно…
Раза 3 присутствовал на «попойке» на которой чинили автомобиль, рестайлили автомобиль, восстанавливали почти с нуля.
Пару лет почти еженедельно наблюдал «решение проблем строительства» (даже «возведения») какого-либо сооружения на очередной попойке.
Да те же приёмы высоких гостей «в бане» или корпоративы (одна из разновидностей) — подобные задачи решают.
0
Раза 3 присутствовал на «попойке» на которой чинили автомобиль, рестайлили автомобиль, восстанавливали почти с нуля.

Это другая профессиональная субкультура, там свой колорит :)
+1
Строго говоря, на тех попойках (я не пил, только присутствовал и подсказывал по мелочи), было только два «автомобильных мастера» — электрик и жестянщик, остальные 6, включая меня — вообще к машинам относились максимум, как водители личного и то не все.
0
Вы даже двух панков без труда найдёте, которые слушают разную музыку, ведут себя и одеваются по-разному.

Ну так панки давно уже на несколько субкультур разделились.

+5
Как геолог, назвал бы свою профессию не субкультурой, а образом жизни. это несколько другое, как мне кажется. Жена -ученый, морской биолог, однако, смею надеяться, мы относимся к одной «субкультуре» по своим взглядам на жизнь, художественным вкусам, и прочему. А так — да, оба бродяги.
+5
Любой особый образ жизни неизбежно формирует свою субкультуру
+1
У любого носителя субкультуры особенности образа жизни во многом будут определяться этой субкультурой
-9

Сравнивать программистов, сидящих в тепле, уюте и попивающих смузи, с геологами, альпинистами, летчиками и тп — это, конечно, сильно.

+9
А в чем принципиальная разница? В геологи тоже идут типа по призванию. Внезапно — есть люди, которым не нравится сидеть в офисе и жить в городе.
-14
В существенно различных рисках и условиях работы. Программистов по этим признакам уместнее причислить к субкультуре офисного планктона.
+6

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


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

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

А те 99% программистов, которые сидят в офисах, пьют смузи и ездят в командировки реже, чем менеджеры по продажам, уже, соотвественно, причислять себя к субкультуре «настоящих» суровых программистов как-бы и не имеют права.

Предлагаю смотреть на вещи объективно: офисный планктон тоже нужен, хотите суровой ылитности — идите в геологи-нефтяники-моряки.
+6

А вы думаете все геологи, биологи, и остальные географы, не вылезают из экспедиций?)
Есть те, кто поля никогда не видел, только на картинах и на даче разве, что.


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

-6
этот пример, был приведён комментатором, касательно факта наличия и у тех и других своей субкультуры

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

0
Само название «планктон» — уже немного оскорбительное, вы не находите? А субкультура людей, которые работают в офисах — конечно есть. Просто у них могут быть очень разные должности и задачи… А субкультура одна, да.
+3
Проблема в том, что вы опять стараетесь уравнять всех под одну гребенку. На хабр иногда приходят не только лишь одни стереотипные программисты, админы и прочие. Могу например сообщить вам, что в море романтики далеко не так много, как кажется с берега. Уже после третьего-четвертого контракта (а зачастую уже после практики и получения рабочего диплома) восторги и романтизм спадают, и гораздо больше волнует возраст и состояние судна, адекватный ли мастер, нет ли филипков или индусов, а к сожалению, есть все чаще, зарплата, овертаймы, из неочевидного — качество еды (вернее даже — качество ее приготовления) и прочие обыденные вещи, к которым примешиваются профессиональные вопросы. Рутина и немного расслабления на переходах, остальное — работа. Так что, простые романтики™ увы, уже не те.
-3
А толку, если геолог \ нефтяник \ моряк получает меньше, чем офисный планктон сеньерского уровня? Получается, что условный геолог по сравнению с офисным планктоном дно, так еще и рисков больше. Получается, что офисный планктон победил.
-1
Тогда нужно носить звание офисного планктона гордо, а не пытаться примазать программистов к каким-то там геологам и морякам. А тут видно, что несмотря на хорошую зарплату, для самооценки чего-то всё-таки не хватает.
0
Да всё нормально с самооценкой у нормальных программистов. Проблема у тех, кто примазывает программистов к планктону.
0
Примерно в том же, в чём разница между мелким клерком и инженером.
0
мелким клерком и инженером

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

0
Мне понравилось определение «офисного планктона» как людей, занимающихся интеллектуальной деятельностью с низкой творческой составляющей.
+1
мне больше нравится определение на лурке:
Офисный планктон (он же «офисное быдло», «канцелярская крыса»,«козявка приказная» и т. п.) — работники умственного труда с пониженной творческой составляющей, проводящие жизнь в офисах и прочих управлениях, но не относимые к инженерам: низшие менеджеры, бухгалтеры, секретутки, и т. д. Являют собой передаточные механизмы, винтики и смазку в механизмах управления, учета, планирования, финансов. Быстрорастущий пролетариат постиндустриального мира.
0
Это вы офисного работника описываете.
А планктон — это уже другое.
0
Ну вообще это был сарказм. Программисты толкают мир и прогресс вперед, и когда программисты напишут ИИ для беспилотных кораблей, моряки начнут исчезать как класс (как сейчас исчезают водители).
0

А офисный планктон разве не двигает прогресс?


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

А когда напишут ИИ для программирования — программисты начнут исчезать как класс: бухгалтера просто будут говорить, что им нужно добавить в отчёт. Кое-где программистов уже заменяют на SCADE, Simulink и т. д. За офисным планктоном будущее!

+3
Надеюсь, это шутка? Потому что когда ИИ научится программировать лучше человека, бухгалтеров уже давно не будет.
+3

Бухгалтера исчезнут раньше. Отчеты в налоговую будут отправляться автоматически, а зарплатные ведомости будут не нужны, т.к. работать будут роботы, чинить их другие роботы, а программировать тех и других — ИИ.

-2

А кто научит ИИ оформлять отчёты? Программисты этого не умеют, их самих учить надо. Нет, бухгалтера и прочие специалисты в предметных областях умрут исчезнут позже:
T — появление ИИ, способного самостоятельно писать программы
T+1 — программисты больше не нужны, бухгалтера обучают ИИ
T+2 — бухгалтера больше не нужны.

+2
ИИ умеет самообучаться. Он читает вышедшие законы и правила и пишет/корректирует программу, которая строит отчет.
«Бухгалтер не нужен, родной» :).
0
Ну или будет человек, конфигурирующий этот ИИ (если ИИ ещё не умеет самообучаться), но это уже не будет бухгалтер в привычном нам понимании
0
А кто научит ИИ оформлять отчёты?
Переоцениваете сложность отчетов.
T+1 — программисты больше не нужны, бухгалтера обучают ИИ
Часто вникали в работу бухгалтера?
+2
Вы серьезно считаете, что обучить ИИ бухгалтерии сложнее, чем программированию?
-1
Зачем вообще отправлять отчеты в налоговую? Не проще ли запретить наличку, и передавать данные по затратам/приходам в режиме онлайн, у плательщика же запрашивать только классификацию расхода? Все отчеты на основе вашей первички налоговая сформирует самостоятельно:-)
0

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

+1
А настоящая проблема совсем в другом — человек пока банально намного дешевле. Особенно с учётом возможных поломок чего угодно. Стоимость небольшой команды по сравнению с топливом (я уж не говорю про груз) среднего контейнеровоза — просто копейки.
0
А стоимость пары вооружённых охранников — ещё меньше, чем команды (на большом судне ведь довольно большая команда, верно?).
0
Экипаж Knock Nevis (длина 450 м) всего 40 человек.
На любом судне крутят штурвал несколько человек посменно. Остальные там с другими задачами. Например, команда механиков всё ещё намного дешевле, чем двигатель который обслужит и починит себя сам.
0
Ну может быть можно сделать такой двигатель, который не будет выходить из строя в течение рейса хотя бы?
У самолётов ведь нет такой проблемы — иначе падал бы каждый второй рейс.
0
1. А ведь и отказывают. В кабине всё ещё 2 пилота есть, которые знают что в таких случаях делать.
2. А ещё их обслуживать надо. У самолётов рейсы короче и обычно в родной порт к своим механикам. А иногда они точно так же возят механиков с собой.
3. Устранение одной небольшой поломки на супертанкере на ходу оплатит зарплату механика на годы вперёд.
И как результат всего выше, авиационный двигатель намного дороже изначально и в эксплуатации.
+7
Внезапно, существуют программисты, которые в отпуске выглядят как настоящие альпинисты.
+1
Пожалуй соглашусь — был такой опыт, коллега… что ни отпуск, так вечно она «в лесах/горах/походах».
+4
А для вас геолог — это обязательно тот, кто с молотком по горам лазает? Открою тайну, сейчас большинство геологов в поле только на студенческой практике бывало, да и керн не всегда носом нюхало. Сидят себе в тепле, уюте, и попивают смузи, рисуя модельки на мощных тачках с качественными дисплеями. Они ж геологи, а не буровики или трубопроводчики. Да даже и геологи-сейсмики не особо в поле катаются, что там делать-то на постоянной основе в 21-м веке?
А про лётчиков — почитайте в блоге Туту.ру, как пилотам живётся, посмотрите видео. Вполне себе комфортная работа в большинстве.
-6
Открою тайну, сейчас большинство геологов в поле только на студенческой практике бывало

В полку офисного планктона прибыло, значит.


почитайте в блоге Туту.ру, как пилотам живётся

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


Вполне себе комфортная работа в большинстве

А вы сами попробуйте каждые пару дней туда-сюда летать то ночью, то днём, то в 5 утра, да по гостиницам ночевать — специфическое удовольствие, даже если просто паксом.

+3
В полку офисного планктона прибыло, значит.

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

А вы сами попробуйте каждые пару дней туда-сюда летать то ночью, то днём, то в 5 утра, да по гостиницам ночевать — специфическое удовольствие, даже если просто паксом.

бгг, и эти люди запрещают ковыряться в носу «планктоном» обзываются
+1
Просто человек из разряда «а баба Яга против». Душа требует возразить по любому поводу, то не так, это не этак.
-1
«планктоном» обзываются

А почему "обзываются"? Не я термин придумал, я лишь констатировал факт. Судя по минусам все так разобиделись, что ваще: видать хотят быть брутальными мачо наравне с нефтяниками и пилотами, но попивая смузи с печеньками в уютном офисе.

+5
Ну кстати термин какой то не очень ясного для меня происхождения. Лично у меня единственное что ассоциируется с планктоном это что то совсем тупое, без мозгов, абсолютно не развивающееся, безучастно плавает в воде и нифига не делеает и т.п.
+2
Вы бы сначала с сутью термина разобрались, а потом бы применяли к месту, глядишь, не вызывали б столько нареканий.
Офисный планктон — современное жаргонное выражение, используемое для обозначения «белых воротничков» — мелких офисных служащих ( (с) Вики)
+1
Ну ептыть. А вы попробуйте в 3 ночи вставать по звонку потому что «У нас тут сплит брейн на проде, давай сука чини бегом, заказчик уже три раза звонил, ЕТА спрашивал».
-3
Не отрицаю, что работа офисного планктона тоже не без элемента героизма.
+1
— Я сам служу, сударыня. Каждый день к 9 утра я должен идти в магистрат. Я не скажу, что это подвиг. Но, вообще, что-то героическое в этом есть.
© Тот самый Мюнгхаузен.
+1
Туше, сударь.
Но тем не менее. Сложно сказать что отнимает больше времени и нервов — работа руками и ногами в поле или работа в офисе, но с постоянными найтшифтами и наркоманским графиком.
+1
Руками/ногами, очень часто, в целом, поздоровее занятие, чем просиживать почти неподвижно весь день.
0
Про геологов и альпинистов не знаю, ученые не субкультура.
+8
Никто не спрашивает, нужна вам субкультура или не нужна. Ваше мнение вообще ничего не значит в данном случае.

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

Ваш Капитан Очевидность.
+6
Вот забавно, за статью в защиту токсичности плюсуют, а за токсичный ответ в слегка одесском стиле — сыпанули минусов…

Двуличная субкультура!!!
+7
А это потому, что здесь представители не одной субкультуры. Красноглазый линуксоид и фронтендер со смузями профессионально относительно близки, но культурно между ними мало общего.
0
Не соглашусь. Оба из них принадлежат к одной субкультуре. Как артисты, хех.
Любая субкультура производит культурные явления — обычаи, предметы, символы, идентифицирующие ее и при этом доступные для наиболее бедных из ее членов.

И такая вещь есть. Во-о-он тот пласт под понятиями OpenSource / Freeware. Явления, которое в равной степени существуют и затрагивают сферу каждого — и красноглазого линуксоида, и фронтендера со смузями.
С трудом можно представить условного булочника, приходящего с работы, встающего к печи и затем раздающего булки на улице. Однако же строки кода, как и строки стихов, сегодня доступны каждому.
0
Понятно, что не всё так примитивно. Два фронтендера с одинаковыми скиллами могут быть мужчиной и женщиной, чёрным и белым. Моя мысль в том, что для фронтендера хипстерская субкультура может быть важней субкультуры айти. Поэтому одни на Хабре постят токсичные статьи, а совcем другие люди минусят токсичные комментарии. Личная культура пересекается примерно как венн диаграмма, и когда в комментариях встречаются люди с противоположных «лепестков», начинается весёлое кидание какашками :) Просто не понимают друг друга.
+6

Тут вспоминается цитата из "Ведьмака":


— Ну чего, ты хочешь меня на хер послать? Милости просим, сука, давай. Я тебя тогда тоже нахер пошлю. Ну и чего? Обнимемся, вместе пойдем, да?

Вот это — нормальная реакция здорового человека.
А жалоба на то, что кто-то с твоим мнением не согласен — ну тааакооооее...

-5
Вот, кстати, живой пример мой коммент в соседней теме habr.com/post/353422/#comment_19481122 собрал тридцать минусов и половина минусов в карме. Думаю, автор топика имел ввиду примерно это. Формируется некая закрытая среда, которая занимается вытеснением неугодных мнений и людей. В результате получается некий бульон из «своих» омерзительно сладковатый на вкус
+6
Хабраюзеры в массе своей не хотят читать глупости. Воистину это сговор и цензура.
-3
Для меня лично 3D моделирование в Excel — это забивание гвоздей микроскопом. Делать это можно, но бессмысленно. Вот и получается, что образуется сладковатая среда забивателей гвоздей микроскопом и эта среда вытесняет любого, кто хочет это делать другими предметами. Но виноваты здесь не хаброюзеры, а сама среда (то есть площадка), давшая пользователям инструменты для формирования такой среды. Так что у меня здесь претензия не к хаброюзерам, а к площадке, а у автора топика должны быть претензии к работодателю
+1
А может вы не на то акцент ставите? Никто же не призывает к именно «3D моделирование в Excel», но демонстрируют ещё один наглядный способ разобраться с 3D (о чём вам там в комментах и написали)
0
Простите, а вам что, кто-то заявлял, что делать тридэ графику не в экселе или делать в экселе не тридэ графику — это плохо? Вас заминусовали за статью об одной из этих вещей? Нет. Дерзайте)
0
3D моделирование это в первую очередь математика. С математикой в Excel более-менее нормально.
-3
Хабраюзеры в массе своей не хотят читать глупости.
Не хотят, поэтому старательно читают, обдумывают, и после даже специально лезут на страницу профиля пользователя, чтобы сирануть в карму. Именно потому, что не хотят, ага :)

Понимаете ли, взрослый, сформировавшийся как личность человек, в отличие от инфантила, если не хочет читать глупости, он их просто… не читает (Внезапно!). А если читает — значит она ему интересна (пусть даже из энтомологического интереса), и здравая форма выражения этого интереса — изложение собственной аргументированной позиции. Конечно, если глупость совсем «за гранью добра и зла» — есть модераторы и почта для жалоб.
+5
Проблематично понять, глупость ты читаешь или нет, пока не прочтёшь. А когда уже прочёл, логично дать обратную связь. Минус комментарию — «такие комментарии здесь не нужны». Минус в карму — «такие пользователи здесь не нужны». Последним, пожалуй, местные несколько злоупотребляют, но я не думаю, что от этого Хабр потерял так уж много.
+2
У нас свободная страна™. Вам никто не мешает создать свой сайт с блекджеком и… и донести ваше, безусловно, очень важное мнение до окружающих.
-2
создать свой сайт с блекджеком

У меня идея одного блекджека давно уже носилась: если персонаж А поставил персонажу Б минус, то персонаж А комеентариев персонажа Б уже не видит, а все остальные — видят. И овцы сыты, и волки целы: персонажа А не раздражает персонаж Б, а персонажа Б не раздражает то, что у него отобрали права голоса.

+3
А потом приходит персонаж Ю и с удивлением наблюдает ресурс, на котором 30 десятка персонажей постят одинаковые посты и пишут одинаковые КЭПские комментарии один под другим, но их никто не замечает.
Действительно, это то, что нужно для данного ресурса!
0

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

0
Уже давно на разных форумах есть опция — скрыть сообщения пользователя. Без минусов/СМСок.
0
Ну мы же не форуме.
Да и как же без срача оживлённого обсуждения очередной неоднозначной статьи/новости?
0
Ну мы же не форуме.
Ну, можно что-то и здесь придумать. Как бы, не очень ново.
Да и как же без срача оживлённого обсуждения очередной неоднозначной статьи/новости?
Так идет себе обсуждение, просто не видите сообщения от тех или иных пользователей.
+1
Вы хотите, чтобы Хабр превратился в какое-нибудь ebanoe.it с первонахами и любителями чужих мамок или в ютуб с хохлосрачами под каждым топиком? Если нет, то почему вы считаете, что без минусования этого не случится?
+3
почему вы считаете, что без минусования этого не случится?

Вот смотрите. Заходим в ветку любого *-срача и пишем комментарий, которые близок к нейтральному, но немного склоняется в одну из сторон (например: "по имеющимся у меня данным мне кажется, что в случае X имело место Y, потому что Z" — вполне рациональная позиция: человек описал имеющиеся у него данные и сделаные им выводы, при этом подчеркнул свою готовность изменить мнение, если будут предоставлены новые данные). При этом он тут же огребает минусов от противников этой точки зрения ("ату его, он против нас!") и… ничего от сторонников ("да ну его, он не за нас"). В результате имеем то, что имеем: карма неудержимо катится в минуса, независимо от того, чей Крым.

+1
Я в последнее время только и делаю, что участвую в срачах в комментариях. Не стесняясь при этом высказывать достаточно экстремальные точки зрения. Моя карма за это время чуть-чуть подросла. Что я делаю не так?
+2
карма неудержимо катится в минуса

И что? Кармадрочерам лучше писать статьи.
0
Вы в курсе, что людей с отрицательной кармой Хабр начинает постепенно урезать в правах (ограничена частота постов и т.п.)? При чём тут кармодрочерство (если я правильно понимаю суть термина)?
0
А Вы в курсе, что кармадрочество (= желание иметь максимальную карму любой ценой, насколько я помню) и стремление не быть урезанным в правах — это несколько разные вещи? Или Ваша позиция сводится к мысли «не хотите минусов — не лезьте в комменты»?
+1
В общем-то, тут действует абсолютно то же правило, что и в жизни. Если хочешь, чтобы тебя слушали — убедись в том, что то, что ты говоришь, кому-то интересно. Или хотя бы не очень раздражает. Иначе тебя тем или иным образом выдавят из компании. В жизни — перестанут приглашать на тусовки. На хабре — насыплют минусов.

xkcd_про_свободу_слова.жпг
0
И мы возвращаемся чуть выше по ветке: получается, что нейтральный по форме и общей позиции, рациональный по сути комментарий здесь в большинстве своём будет «не интересен» и «очень раздражает»? Нет, меня, конечно, тоже не раз называли троллем, когда я всего лишь пытался сделать из слов собеседника какие-то выводы (не здесь, на другом сайте)…
+1
А где вы берёте такие комментарии? Обычно если я вижу комментарий в минусах, то он либо хамский по форме, либо глупый по содержанию. А в идеале — и то, и другое сразу.
+2
То есть мы сейчас обсуждаем явления, с которым ни я, ни вы лично не встречались. Мне кажется, это неконструктивно)
0
Ок, пример: комментарий +36/-2 совпал с -2 кармы (другие комментарии в тот день минусов не собирали)
Всё как в жизни? Не надо говорить, если тебя слушать не хотят? Не надо говорить то, что раздражает?
Ха, ха, ха.
0
А сейчас ваш комментарий не получил плюсов, а плюс в карму прилетел. Как вам такой контраргумент?)
0
Спасибо, но суть всё же была не в том.
Если бы плюсы и минусы к комментами напрямую конвертились в оценку того, хотят тебя здесь слушать или нет — вот тогда б это было показательно. А сейчас зачастую не понятно что людям не понравилось вообще.
0
Вот, кстати, требование оставлять развёрнутое объяснение под каждым минусом в карму я бы поддержал. Видел похожую систему на одном сайте, мне понравилось.
0
А сейчас ваш комментарий не получил плюсов, а плюс в карму прилетел. Как вам такой контраргумент?)

Я бы с удовольствием послушал оратора. Но ему накидали минусов в карму (-1), но у меня нету прав поставить ему (+1)
В итоге оратора «запинали».
Подозреваю, если человек выскажет свое «глупое, смешное и никому не интересное мнение» в ветке «не по профилю» (про БД выскажется спец по JS/C++), то в своем «профиле» — он уже тоже ничего не сможет сказать :)
Карму слили в «непрофильном» наказав за любопытсво, а в «профильном» это и так спецам понятно, зачем поошрять.

Насчет большинства и интереса: Аристотель как-то написал что у мухи 8 ног и ~2000 лет никто не удосужился это проверить до Карла Линея. Интересно, а скольким до него было сказано «У мухи 6 ног ?! Да ты, парень, идиот. Все знают что их 8!!! Слышишь, неполноценный умственно, 8! С Аристотеля!!!»
+1
Не обижайтесь, но это очень забавно, когда про аристотелей, карлов линнеев и прочих джордано брунов пишут люди, которые ниасилили написать пост и нарастить кармическую подушку безопасности.
0
Не обижайтесь, но это очень забавно, когда про аристотелей, карлов линнеев и прочих джордано брунов пишут люди, которые ниасилили написать пост и нарастить кармическую подушку безопасности.

Я так понимаю, что по существу приведенного сценария и исторического факта сказать нечего. Разве что добавить язвительности, которая сформировала не плохой эмоциональный посыл, за который поставили +1.
Случайный социальный эксперимент :)

Я бы поддержал Ваше предложение с пояснениями по карме в чуть измененной форме: требование оставлять развёрнутое достаточно нескольких градаций проф/социальный/личное и т.д. объяснение под каждым минусом (плюсом) в карму
0
А это и было высказывание по существу. Если вы умный и без ваших мыслей Хабр много потеряет — накопите этих мыслей побольше и напишите пост. Если не получается написать такой пост, то имеет место логическое отрицание условия из прошлого предложения.

Пример с мухой — он, мягко говоря, хрестоматийный. А говоря твёрдо — боян. Я его, помнится, приводил ещё на локальном общажном форуме, когда просил меня разбанить после того, как несколько раз высказал своё ценное мнение по различным вопросам. Но одмин был глух к мольбам. И, в общем-то, совершенно правильно. Хреновый из меня тогда был Карл Линней.
0
А это и было высказывание по существу.

Мой вопрос был прост: Как не имеющий права голоса может высказаться в поддержку того, с чьими высказываниями он согласен, но не согласно «голосующее большинство»? По вашим правилам, порог вхождения крайне высок(запретительный) :)
Если вы умный и без ваших мыслей Хабр много потеряет — накопите этих мыслей побольше и напишите пост.

У Вас не верная предпосылка. Репутация Хабра — любопытная штука, хороший механизм монетизации. Для владельцев ресурса :)
Не очень понятно, почему я должнен мои «гениальные мысли» выложить на Хабр, а не «замутить Свой Крутой Бизнес»? :)
Если не получается написать такой пост, то имеет место логическое отрицание условия из прошлого предложения.

В общем-то это и есть наглядный пример мехнизма «токсичности» :)
Не устроило большинство (или обладающего Правом), просто "-1" без пояснения и играй в угадайку :)
На мой взгляд, от того что «пример хрестоматийный» или «боян» разбрасываться его практической пользой — сомнительная практика.
Если форум созданы для обмена мнениями, это одно, если форумы созданы удовлетворить большинство — это другое :)
С точки зрения бизнеса — сценарий «большинства» предпочтителен:)

+1
Это у вас неверная предпосылка. Вы почему-то считаете, будто каждое мнение априори кому-то интересно, а свобода самовыражения является основополагающей ценностью. Это невероятно далеко от правды.
0
Вы почему-то считаете, будто каждое мнение априори кому-то интересно,

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

Считайте это как «социальную эволюцию». Время от времени появляются новые виды (мысли). Каких-то «уродцев» выбрасывают, какие-то выживают и развиваются двигая общество вперед и защищая его.
Нету новых мыслей — застой.
Вы предлагаете убрать свободу самовыржения? Или оставить только управляемую «социальную эволюцию»?
+1
Эволюция — очень хороший пример. Если регулярно выкашивать случайно выбранные 10% популяции, эволюция продолжит работать как ни в чём не бывало (при условии, что популяция успевает восполнять потери). На одного заминусованного комментатора придутся девять таких, кто сумеет сформулировать примерно ту же мысль, но более куртуазно. А если не придутся — значит, либо мысль очень плоха, и чёрт с ней; либо мысль очень хороша, и тогда её автор способен родить пост.

P.S. Если что, я не хочу показаться высокомерным. Я в своё время по идеологическим соображениям гордо выпиливался с хабра, имея в активе статьи с рейтингом около 200. Я думал, это что-то будет значить. Неа, практически никто и не заметил. Система работает по принципу взаимозаменяемости винтиков. И это нормально.
0
Если регулярно выкашивать случайно выбранные 10% популяции, эволюция продолжит работать как ни в чём не бывало

Эволюция невозможна без отбора.

Все верно, за исключением проблемы масштабирования.
Если популяция ниже определеного порога, она вырождается и умирает.
Если будем выкашивать рандомно 10% в коллектие в сотни… тысячи… миллионы единиц- «эволюция» продолжится, но с меньшей скоростью.
А если такое будет в популяции в 5..20..100 единиц?
Не проявится ли «выученная беспомощность» со временем — зачем генерить повторно мысль, если ее выкосили включив в рандомные 10%? Остальным 90% тоже не сахар. Такие прецеденты тоже были в истории :)
+1
Ну, что-то я не вижу здесь недостатка в комментаторах)
+1
Извините, оффтоп. Прокомментирую вашу аналогию.
Если популяция ниже определеного порога, она вырождается и умирает.
Нет.
Есть такое понятие «бутылочное горлышко». Его прохождение часто весьма способствует эволюционным изменениям.
Если будем выкашивать рандомно 10% в коллектие в сотни… тысячи… миллионы единиц- «эволюция» продолжится, но с меньшей скоростью.
Нет.
Высокая численность популяции является эффективным тормозом эволюции. Можете погуглить «кошмар Дженкина» и «дилемму Холдейна».
/оффтоп.
0
Есть такое понятие «бутылочное горлышко».

Вы имеете ввиду этот «Эффект бутылочного горлышка»
Цифры что я видел: Людей, если меньше 150..200 в племени, вымирает за порядка 5 поколений. Тоже падение устойчивости к внешним воздействиям.
По животным 100..1000 в течении 50..100 лет.
«кошмар Дженкина» ...«дилемму Холдейна»

Не могу ничего сказать, но материалы относятся к очень давним временам, а в свете данных последних 10 лет генетики открыты горизонтальный перенос генов, и теория о резких эволюционных скачках в следствии накопившихся небольших генетических изменений.
Но полагаю, что далее тут эту тему развивать не стоит :)
0
Да, именно его.
Там несколько не тот механизм. При падении численности популяции увеличивается вероятность вымирания. Бутылочное горлышко можно и не пройти. Но ни о каком детерминированном вымирании речи и близко не идет.

Про горизонтальный перенос генов я еще в детстве слышал, это очень сильно не десять лет. Теория о резких скачках… Не ловлю. Не прерывистого равновесия? Если она, то это 70-е, и несколько не о том.

Ну и да, если что, не развивать тему всегда готов :)
В конце концов, это был оффтоп.
+1

Вы как в том анекдоте.


Грибник заблудилися в лесу и кричит "Ау! Ау!"
На шум из кустов вылезает сонный медведь.
— Мужик, чего орёшь?
— Заблудился я, надеюсь, услышит кто.
— Ну я услышал. Тебе сильно помогло?

Лично мне — нет.

0
Хм. Вот, кстати, ваш пример меня удивляет. Как вас угораздило?
0

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

0
Где вы наловили столько минусов в карму? По одному-два за случайные комменты? Или всё-таки был какой-то центральный момент неприятия вас сообществом?
0
По одному-два за случайные комменты на протяжении двух лет (последняя моя публицкация была в 2016). Неубывающая карма (после окончания временных «бустов») была, кажется, около 50.
0
Кстати: а может такое быть, что у мухи, которую исследовал Аристотель, было действительно 8 ног? Возможно, какой-то вымерший впоследствии вид?
0
Насколько я помню, там вообще какая-то мутная история. В том смысле, что её растиражированная версия не вполне совпадает с тем, что было на самом деле. Но детали моя память не сохранила.
0
Вымерший впоследствии вид — однозначно нет. Количество ног таксономически различается не на видовом уровне, а на уровне классов. Различия не между человеком и обезьяной, а между человеком и птицей.

Теоретически это могло быть уродство, сбой в онтогенезе. Если дать эмбриологу возможность, он вам Слейпнира вырастит, а не то что муху восьминогую. Ну может, вырастить не получится, но родит запросто.
0
Раз, два, три… в общем, кто видел источники (пусть даже в переводе) — опровергают.
Так что вопрос больше в источнике байки про то, что Аристотель это писал :)
+1
Или Ваша позиция сводится к мысли «не хотите минусов — не лезьте в комменты»?

Это уже общеизвестный факт: за посты карму плюсуют, за комменты — минусуют.
0
есть разница между хамством и конструктивной критикой. Из ваших комментариев, как, впрочем, и статьи, очевидно, что вы пропагандируете первое.
0
Жить в чёрно-белом мире легко и просто. Жалко что наш мир на него не совсем похож.
+1
Хочется, но не можется — отсюда такие истеричные посты, ибо эмоции захлёстывают. Хочется всех послать, но в ответ могут послать дальше и крутое мачо начинает обижаться. Они просто не пробовали когда их только пинают, а стоит немного попробовать.
-8
Программист — это человек, который отдает свое время за деньги. Как врач. Как сантехник. Как уборщица. Он всегда хочет поработать меньше и получить больше. Вот и весь секрет. Это не детский сад и не субкультура. Это — ПРОФЕССИЯ.

А работодатель всегда хочет заплатить меньше. Отсюда и придумываются всякие набросы типа «корпоративная культура», «мы — семья», «мы — избранные», «айти-нация» и т.п.

вот как здесь, например
+6
Люблю работать. Вот прёт бывает и всё. Хоть сутками сиди.
Выходит, я не программист.
+1
Я бы различал несколько профессиональных субкультур в профессии программиста, причём некоторые из них выходят далеко за рамки профессии. Некоторых программистов точно можно отнести к субкультуре «офисный планктон» работников умственного труда с пониженной творческой составляющей :), а некоторых к якки, фрилансерам, дауншифтерам и т. п.
0
Возможно, когда мне будет за 30, я так же начну работать от звонка до звонка только ради зарплаты.
+1

Не волнуйтесь, мне уже за 40, а "от звонка до звонка" всё ещё не хочется — интересно работать жеж, ёпрст!

0
Программист — это человек, который программирует, а то, что он получает за это, деньги, удовольствие или что-то ещё — это дело третье…
0
По вашей логике, получается, что некоммерческое/Freeware/OpenSource ПО присылают марсиане.
Ибо под понятие «поработать меньше и получить больше» никак не попадает.
+4
Вы одновременно и правы и нет. Правы в том, что изменения есть и будут продолжаться, если раньше разработчик и гик это было практически синонимы, то теперь эти разработчики социализируются и получается, что чаще перевешивает: `разработчик != гик`. А не правы, что это только лишь плохо, меня лично пусть раздражает тот же аджайл, с его бесконечной тратой времени, но тенденции, что люди пытаются оптимизовать подход к работе с интеграцией во множество систем, пусть аналитика, продажи и что-либо ещё — это я одобряю.
А `сюсюканье` это от социализации.

-2
У меня от слова гик встаёт(ну вы поняли) перед глазами нагеленный полупокер в розовой футболочке с айтишным принтом, тыщачий маникюренными пальцами в айфончик, проставляя лайки в инстушечку.Как в фемили гае, в серии про миллениалов
0
Небось, ещё и смузи прихлёбывает при этом, закусывая фалафелем.
0
напрасно. Geek это кто-то, чем-то чрезвычайно увлечённый (не обязательно компьютерами), что от этого иногда страдает внешний вид и социализированность.
+1
Не совсем ясно, что мешает автору выстроить работу с заказчиком (будь то внутренний или внешний, неважно) так, что есть условная команда матерящихся через слово инженеров, крепко знающих своё дело, но не общающихся с душевно-тонкими личностями с «той стороны» и команда пахнущих ромашками менеджеров проекта, которые как раз и берут задачу «презентации» команды на себя?

Проще если. Клиента встречает метросексуал, пишет код ему бородатый вечно пьяный хакер, а по пятницам они вместе обсуждают проекты в ближайшей рюмочной?

Или вы заставляете инженеров говорить с бизнесом? Тогда может в этом проблема?
+29
В статье речь о состоянии внутри коллектива, а не про общение заказчик-исполнитель.
Автор говорит о том что в рабочей обстановке в последнее время культивируется «безопасное и мягкое общение» и именно против этого тренда он и высказывается.
+1
Ну так и я про тоже. Выделите тех, кому не нравится «безопасное» общение в отдельный коллектив, пусть общаются между собой, как хотят. Если это повышает производительность — почему бы нет?
Разумеется, такой коллектив и его представителей следует максимально изолировать от тех, кто против их стиля общения.
+2
Это вполне разумно, но на деле всегда могут всплыть нюансы, из-за которых такая четкая изоляция будет невозможна — команды изначально маленькие, дробить еще меньше не выйдет, либо придется делать перестановки, что также скажется на эффективности труда (по крайней мере на первых парах), нового сотрудника зачастую тяжело отнести к тому или иному «лагерю», он может раскрыться только со временем. А даже если удастся поделить именно так, то коммуникацию все равно не прервешь, так или иначе будут видеть друг друга, хоть на той же кухне.
-1
Я все же хочу надеяться, что выделять в отдельный «коллектив» придется все-таки быдло, а не адекватных людей. Хотя судя по рейтингу статьи — до этого еще далеко.
0
Тонкие метросексуалы сломаются от попыток общения с вечно пьяными матершинниками, и ничего из такой затеи не выйдет…
0
Но ведь, если такая статья появилась, значит, сегодня выигрывают «метросексуалы»!
+57
Почитайте Карнеги, лесть лицемерие и подковерные интриги — это норма человеческого общения, так же лицемерно названная этикетом. Так везде и всегда, я Вас огорчу, но ИТшники и здесь ни разу не особенные.
А в профессиональном плане, кто Вам сказал что критиковать людей нельзя? Можно и нужно, но критиковать можно по разному. Кто Вам сказал что людей хантят печеньками? Что у Вас вообще в голове творится?
Вы тут продавливаете общество «трамвайных хамов», но открою Вам секрет это работает только на первых порах, а в перспективе дает кучу проблем которые никому не нужны.
Да и не стоит считать всех ИТшников слабовольными безхарактерными хипстерами, поверьте это далеко не так.

-2
Я против культивирования инфантилизма и гиперопеки. Вы спорите с вашими собственными высказываниями. Трамвайные хамы откуда-то взялись… Заранее известно моё мнение обо всех айтишниках… Прямо пособие по демагогии.
+5
Какая еще гиперопека и инфантилизм? Кроме ярлыков я здесь ничего не вижу? Я 10 лет в ИТ и могу Вам написать прямо противоположную картину.
И со своими утверждениями я не спорю, я пытался, видимо не совсем удачно, сказать что преимущество «трамвайного хама» весьма зыбкое и перспективе приносит ему огромную кучу проблем ради разовой эфемерной выгоды и тем более на уровне трамвайных хамов невозможно построить профессиональные отношения.
+12
Вы приписываете мне утверждение и на этом строите критику. Это называется демагогия. Хотите спорить аргументированно — приводите цитаты из статьи. Я достаточно ясно излагаю свои мысли, они не нуждаются в вашем толковании да ещё и с уничижительными эпитетами.
+7
Я достаточно ясно излагаю свои мысли, они не нуждаются в вашем толковании да ещё и с уничижительными эпитетами.

Вы достаточно ясно излагаете мысли для себя..:


Любые предложения люди понимают иначе, чем тот, кто их вносит.
Следствия:
Даже если ваше объяснение настолько ясно, что исключает всякое ложное толкование, всё равно найдется человек, который поймет вас неправильно.
Если вы уверены, что ваш поступок встретит всеобщее одобрение, кому-то он обязательно не понравится. — Третий закон Чизхолма

PS Я вот ваш текст не осилил — нытьё и плачь, с просьбой вернуть хамство… И откуда-то внезапно берутся розовые сопли и карамельные рельсы… Ау, вы про какой айти-то хоть? Мировое? Нет такого — есть европейское, есть американское и т.д. Нет, ситуация с линуксом, конечно не самая приятная, но на галерах, например, никаких изменений нет. В ынтырпрайзе — тоже не особо заметно (благо галеры наполовину с ним пересекаются).

-20
Не могли бы вы перестать? Опять то же самое, текст вы не читали, но критикуете с уничижительными эпитетами.
+26

Вы же сами ратуете за прямое, без обиняков выражение мнений. А как получили такое мнение о своей работе — так сразу просьба перестать?))))

-4
Мы ратуем за прямое мнение компетентных людей, а не взвизги «не читал, но осуждаю».
-1
Я утверждаю, что конструктивая критика полезна. Пока что все возмущённые конструктивизма не проявляют, зато прямо блещут своей тактичностью. Довольно странно, что люди, не прочитавшие текст приписывают мне какое-то мнение и выражают его в поразительно невежливой форме. Почему меня называют нытиком, плаксой и хамом в комментариях те самые люди, которых до глубины души возмутила моя статья? Потому, что не могут её прочитать и судят на основании своих домыслов?
+13

Чувак, если я "ниасилил" текст, это не значит, что я его не читал. Я осилил (давясь) первые ~40% и последние два абзаца. Чтобы иметь представление о чём речь — достаточно. Если ты умудрился запихнуть в указанный мной кусок все свои "гиперболы" (на самом деле адовые перегибы в большинстве случаев) — сугубо твои, как автора, проблемы, т.к. существенно снижаются твои шансы быть понятым.


В общем я "ниасилил" твой текст, а ты "ниасилил" обычную, даже без мата, критику… за которую типа ратовал в текстовке. Никакого уважения такое поведение вызвать не может.

-11
Позвольте ответить вам вашим стилем.

У вас, вероятно, серьёзные проблемы. Вы не прочитали даже половину текста, но так перевозбудились, что бросились гневно писать комментарий. Мне не особо интересно мнение такого формата.
+4
В общем я «ниасилил» твой текст, а ты «ниасилил» обычную, даже без мата, критику… за которую типа ратовал в текстовке. Никакого уважения такое поведение вызвать не может.

А где там, извиняюсь, критика?

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

Так же, извиняюсь, критика?
-1
Но ведь в статье речь не о «вернуть хамство», никто не предлагает вам «отбирать места у беременных и вперед бабушек лезть в очередь».
Тут скорее речь о том, что если человек что-то делает плохо, не делает то, что ему положено, ну или просто исключительный идиот, не надо его ограждать от критики. Надо говорить «Ваня, ты дибилоид, ну как так можно», в идеале еще показать ошибки и научить как правильно.
+7
не надо его ограждать от критики. Надо говорить «Ваня, ты дибилоид, ну как так можно», в идеале еще показать ошибки и научить как правильно.

Это разные вещи, которые любители хамства не понимают. «Ты дебилоид» — это не критика, это прямое оскорбление. То, что и называется токсичностью.
«Ты накосячил, сделал так, а надо было вот так» — критика. Здесь нет оскорблений, но нет и никакого ограждения от критики.
0

"возможность накричать на приятеля — признак верной крепкой дружбы" ©

+1
Весьма манипулятивная фраза, да и мы не о друзьях говорим, а коллегах. Это не всегда пересекающиеся множества.
0
А что такое галеры? Извините, тут просто со сленгом проблемы у некоторых)
+1
Вообще мысль автора понятна. Но времена меняются, и программисты перестают быть гиками с низкой социализацией. Не все менеджеры это еще поняли, это да. Дайте им время )
+33
Вообще мысль автора понятна.
А мне нихрена не понятна: навалена куча каких-то предрассудков, ни грамма логики, никаких выводов. Так и хочется ответить на это:
Идите-ка вы в жопу с вашей «токсичностью»!
чем-то вроде этого:
Иди-ка ты автор в жопу с своими «статьями»! Набросал две страницы ключевых слов и теперь рассказываешь в комментариях «я этого не писал», «вы мне это приписываете». Дай я открою тебе глаза: ты вообще не написал на одной умной мысли кроме того факта, что без критики и честных фидбеков мы никуда никуда не поедем. Вот тебе честный фидбек: засунь ты себе эту статью обратно в жопу черновики. И не связывай рабочие навыки, привычку материться и твердость гениталий. Слово "!@#" тебе, как видишь, никак не помогло.
Дело, на самом деле, в том, что вежливость, как заметили тут многие — это этикет или протокол взаимодействия между работниками. Быть невежливым и вызывать какие-либо втч отрицательные эмоции у других просто мешает работе. Пример с дальнобойщиком и продавщицей здесь неуместен, поскольку, во-первых любая женщина и любой мужчина предпочтёт вежливое обращение к ним вне зависимости от того, как они сами обращаются. Во-вторых, их взаимодействие длится несколько минут от силы, легче потерпеть.

Что касается стрессоустойчивости и «запрет на негатив» — то это просто манипуляция фактами. Админ стрессоустойчив не потому он матерится, и матерится он не потому что он стрессоустойчив. Он матерится потому что он — быдло, а на работе его держат потому что, наверное, достоинства превышают недостатки. И, наконец, если некомпетентный джун тебе пятый раз присылает говнокод на ревью, а ты не видишь никакого решения кроме как «вызвать негативные эмоции» чтобы решить проблему, то ты — некомпетентеный начальник. Когда встречаются два некомпетентных человека ни трэш-ток, ни размазывание розовых соплей не помогают, да.
+5
Не понимаю, почему вы все хватаетесь за крайности?

Electrohedgehog говорит о насаждаемой избыточной толерантности и её последствиях. О ситуациях, когда вы упомянутому ранее джуну 18 раз указали на ошибки, дали ссылки на соответствующую литературу, а получили на 19й раз всё тот же говнокод. И вот кроме «джун, ты !@#» тут и не скажешь ничего.

Вы же говорите о ситуациях, когда джуна с первой итерацией кода посылают в !@# и громко нецензурно критикуют вейп, бороду и спиннер этого джуна, ничего по коду конкретного не говоря. И да, такое поведение действительно токсично.

Лично мне проще работать в коллективах «твой отдел — твоя семья», где действительно доверительные отношения и никто ни с кем не сюсюкается.
Возможно кому-то нравятся коллективы с большим этикетом — их право.

Но насаждение «этичной толерантности» чуть ли не силой это явный перебор на мой взгляд.
+12
И вот кроме «джун, ты !@#» тут и не скажешь ничего.
Я так и написал: некомпетентный руководитель. Разве что мне здесь кто-то объяснит зачем вообще человека обзывать !@#ем и как это помогает рабочим отношениям.
Вы же говорите о ситуациях, когда джуна с первой итерацией кода посылают в !@#
Где?
Лично мне проще работать в коллективах «твой отдел — твоя семья», где действительно доверительные отношения и никто ни с кем не сюсюкается.
Вероятно, не у всех ваших сотрудников слово "!@#" — нормальное обращение в семье и вполне возможно, что они страдают из-за вас на работе и вполне возможно, что это отражается на их производительности. Кроме того, лично мне совершенно не нужны ваши семейные отношения на работе.
Но насаждение «этичной толерантности» чуть ли не силой это явный перебор на мой взгляд.
Силой — это бьют, что ли? Заставляют отжиматься? Да, явный перебор, согласен.
+3

Вы передергиваете.


Люди могут страдать не только от того, что кто-то материться, но и от того, что они ощущают давление в направлении рамок.


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


Создать общий свод правил о том, как нужно себя вести, что-бы любой коллектив с любым составом уживался на 5 — невозможно. Вас раздражает семейность, кого-то формальность, кого-то другого что нибудь еще. И каждый может привести доводы, почему такой или иной стиль поведения продуктивней.


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

0
Почему нужно договариваться с матершинниками о том, что им не стоит материться? Это ни разу не норма современного общества. КоАП говорит, что мат это мелкое хулиганство. Кроме того, мат говорит о скудности в выражении мыслей и эмоций. Так же и в выражении того, что человек делает что-то не так и не то — есть великое множество способов сказать одно и тоже и с разной степенью напора, дружелюбности и мотивации.
+1
Если хоть немного посмотреть по сторонам, может сложиться вполне обоснованное впечатление, что мат как раз-таки стал нормой современного общества.
0
а КОАП 20.1 нельзя так трактовать? или если лично послали, то КОАП 5.61 (но это уже оскорбление)?
0

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

0
погуглил трактовки статьи, спасибо что обратили внимание на заблуждение. буду знать.
0
Коммуникативный слой русского языка богат и разнообразен. И очень часто (надеюсь, пока) огульно и бездумно до нельзя упрощяется и искажается интерпретаторами. Вот тут введение в тему, очень всем рекомендую: amarinn.livejournal.com/1122199.html
+1
Люди могут страдать не только от того, что кто-то материться, но и от того, что они ощущают давление в направлении рамок.

Самый банальный пример, это когда ЧР делает замечание о том как стоит и не стоит разговаривать людям, которые уже давным давно на ты.
Приватные бесседы — личное дело каждого. Если ЧР слышит приватную бесседу — то она больше не приватная. Если вы открыты к критике так, как бахвалится этим автор, то никакого давления от замечания испытывать не будете.
Создать общий свод правил о том, как нужно себя вести, что-бы любой коллектив с любым составом уживался на 5 — невозможно. Вас раздражает семейность, кого-то формальность, кого-то другого что нибудь еще. И каждый может привести доводы, почему такой или иной стиль поведения продуктивней.
Нет. Во-первых, продуктивность тут вторична. Во-вторых, пилоты используют специальный лексикон на англ языке в полете потому что о нем смогли договориться. Ваши интернеты пользуют доисторический HTTP потому что о нем смогли договориться. Названия живых организмов все на латинском потому что о нем смогли договориться. Люди по умолчанию вежливы друг с другом потому что об этом смогли договориться и свидетельство тому — несколько статей админ кодекса. Вопрос: сможете ли вы договориться на работе повсеместно использовать какой-то другой стиль кроме формального? А если новый сотрудник — то заново договариваться? На это может уйти много времени, что как-то не вяжется с продуктивностью.
Единственный способ создать функционирующее общество, это не вмешиваться в дела, которые вас не касаются.
Это у вас пережиток советского воспитания: «не лезь», «не твое дело», «ты что самый умный?». Об этом можно вести отдельную дискуссию, но суть в том, что это, скорее всего, плохо и неправильно, и, ИМХО, одна из основных причин почему люди из СНГ по-прежнему хотят свалить на запад.
Если кто-то любит материться, пусть матерится.
Так, где границу проведем? По какую сторону от границы будет огнестрельное оружие?
Если вам это мешает — договоритесь. Это отлично работает в современных обществах (меритократический капитализм).
Хер это а не работает. Если вы заглянете в среднестатистический российский подъезд, то вы сразу поймёте, что 50 человек не могут договориться просто ни о чем. Не умеют-с.
0
В советском воспитании скорее наоборот пропагандировалось постоянно вмешательство «общественности» в личные и семейные дела. А «не твое дело» — это защитная реакция.
0
Если ЧР слышит приватную бесседу — то она больше не приватная.

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


Во-вторых...

Все что вы тут перечислили — это языки. Но существуют еще и межличностные отношения. Конечно, на работе можно ограничится лишь рабочими вопросами. Но люди есть люди все равно будут симпатия и антипатия. И это уже за рамками формального общения.


Это у вас пережиток советского воспитания

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


Так, где границу проведем? По какую сторону от границы будет огнестрельное оружие?

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


Хер это а не работает.

Это работает лучше чем автократия. Если есть проблема, то ей занимаются те кто замешан, а не все вокруг. А то что в РФ происходит это никак не пример.

0
Одно дело если вас попросят говорить тише или в другом месте, другое, когда вас начнут поучать как друг друга называть.
Вот открытие: у всего есть мера.
Но люди есть люди все равно будут симпатия и антипатия. И это уже за рамками формального общения.
Неформальные отношения с хорошо знакомыми людьми на работе мешают этой самой работе — инфа 100%.
Я вырос не на пост советском пространстве, а в очень даже западном Израиле.
Вполне вписывается в мои представления об Израиле.
Причем тут оружие вообще?
Подумайте.
0
Вот открытие: у всего есть мера.

И вот ее нарушают. Об этом и статья.


Неформальные отношения с хорошо знакомыми людьми на работе мешают этой самой работе — инфа 100%.

Неформальное общение это не только покурилки. Нелюбить человека можно за то как делает код ревью. Можно весь отдел похерить, с плохим менеджером, который только формально общается — инфа 100%ю


Вполне вписывается в мои представления об Израиле.

Какие?


Подумайте.

Я подумал, и все равно никакой связи не вижу.


P.S.
Мне не нравится ваш токсичный стиль общения.

0
Мне не нравится ваш токсичный стиль общения.
Это не стиль общения а объективная критика, см. статью.
0

Нет, вы токсичный человек и я чувствую себя оскорбленным.


P.S.
Кроме политизированных шуток, я действительно считаю ваш стиль общения хамским.

+5

Интересно, а что если после того как вы скажите джуну идика ты на @*_#, он вежливо попросил тебя выйти на улицу уточнить лично с ним ваши претензии. Возможно ваш пыл сразу поубаватся. Нельзя давать себя оскорблять, нужно это мгновенно пресекать любым способом, иначе у человека это войдёт в норму. Как тут писали — вежливость и порядочность на работе — это протокол общения

+3
Не защищаю хамство, но думаю, что предложение пойти выйти может сыграть злую шутку. Допустим, они выходят на улицу обсудить претензии, где человека (думаю, опыт в не важен, в разумных пределах) посылают на слово из четырех букв еще раз. Что дальше?

Вы намекаете на силовое наказание обидчика. Успешное наказание легко попадает под статью УК, с учетом того, что в травматологии пострадавшего будут едва ли не пытать: «итак, я вам предлагал признаться в том, что вас побили, и вы согласились? Нет? То есть вы решили скрыть факт того, что вас побили? И кто именно вас не побил?..».

А дальше как я со стороны программиста вижу влияние этого на дальнейшую карьеру: коллеги запомнят обе стороны конфликта как «чуваков, которые подрались в офисе». Именно так, без лишних деталей. Когда через 5 лет у них рекрутер спросит «знаешь ли ты Персону1» именно этот прецедент и всплывет в памяти, с погрешностью на испорченный телефон и забытые со временем детали.

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

С точки зрения кадровика (и всех помошниц, 90% из которых станут кадровиками других компаний через 5 лет) на корпоративе после выпивки это будут 2 обезьяны с гранатой, а сам случай — опасный прецедент, другие могут взять на вооружение.

С точки зрения топ-менеджмента это как минимум неприятная мелочь, а как максимум: потери репутации.

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

Можно подумать, что быть *вежливым* и «вызывать какие-либо втч отрицательные эмоции у других» — работе не мешает. *Эмоции* — как бы, вообще не та вещь, которая — безусловно — уместна «на работе».
И, наконец, если некомпетентный джун тебе пятый раз присылает говнокод на ревью, а ты не видишь никакого решения кроме как «вызвать негативные эмоции» чтобы решить проблему, то ты — некомпетентеный начальник.

Даже опуская вариант, когда «вызвать негативные эмоции» — это и есть «решить проблему», ваше обобщение с «некомпетентностью»… это такое. Сказать, что «говнокод» — это «говнокод», если и является «некомпетентностью», то несколько в другой области :-)
+1
Ничего не понял. Походу вы с автором на каком-то непонятном наречии пишете. Или да, я дурак.
+1
Сказать, что говнокод — говнокод допустимо в целом, сказать, что его автор — говнокодер — нет.
+1
Допустим, в некотором отделе разработчики отлаживают код перед сдачей — потому что сроки на неделю сдвинули, зато попросили экстренных фич, при этом на сдаче контракта нужен красивый прототип, который примут as is, а потом будет пол-года на устранение багов и это согласовано всеми сторонами.
Но фичи ломают архитектуру и вообще не вписываются, зато ОЧЕНЬ нужны.
В воздухе плавает запах дедлайна, свежих багов и пара топоров, которые не падают из-за густого мата, что не нравится нежным девочкам-тестировщицам и вызывает негативные эмоции.
Внимание, вопрос: и что делать в таком случае?
0
В итоге — да, но у нас была пара других кабинетов.
А если бы это был модный openspace? Или в других кабинетах не было бы мест?
0
MVP же делают чтоб было рабочим и манящим. Код совсем прототипов выбрасывается и пилится нормальный с архитектурой, для остальных случаев костыли и затычки превращают в куски архитектуры, возможно накапливая некоторый тех.долг относительно унификации и идиоматики.
0
Сомневаюсь, что понятна. Социализация не означает, что надо устраивать на работе детский сад.
-1
Так и я о том. Программисты сегодня существа гораздо более социальные изначально, поэтому не надо устраивать детский сад.
+31
Этикет — это нормы поведения (в том числе общения), грубо говоря — спецификация, когда всем комфортно, все знают какая будет реакция на определенный сигнал. Если я иду на деловую встречу — ужин, по приглашению особы женского пола, то я знаю, что платить за ужин будет она (так принято по этикету). Мне не нужно гадать и морщить лоб по этому поводу. А лицемерие — это совершенно другая вещь. Это когда одному за глаза улыбаешься, а другому рассказываешь какое он $@#$ на палочке.

Есть люди позитивные, но с характером и по делу — в таком случае и крепкое словцо может перепасть, но только за дело. Таких ценю.

А есть негативные, которые даже в положительных вещах видят негатив, от них только и слышны жалобы и нытье, да еще и культура общения — мат-перемат. Вот такие и попадают под определение — токсичных людей. Которые помимо своего отравленного желчью внутреннего мира пытаются заразить всех остальных. Вот таким, я считаю, не место в коллективе.
+4
Кто Вам сказал что людей хантят печеньками? Что у Вас вообще в голове творится?

Это что у Вас в голове творится? Где в статье про то, что хантят печеньками? Автор написал о том, что в вакансиях очень часто есть упоминание про печеньки. Я тоже это постоянно вижу и меня тоже это выводит из равновесия. При этом никто не говорит, что печеньки не нужны, с ними лучше чем без них. Но, блин, есть много вещей важнее этого. Кресло удобное, например. Или не адовый опенспейс на 100 человек, а маленькие кабинеты и т.д.
0
Просто «печеньки», видимо, один из самых выгодных способов мотивации, как по критерию «эффективность/стоимость», так и по стоимости реализации. Так что их все внедряют, а многие на этом и останавливаются.
0
Каким образом халявные печеньки могут мотивировать взрослого профессионала?
+1
Ну, во-первых, мотивировать нужно не только «взрослых профессионалов», но еще и «невзрослых профессионалов», «невзрослых непрофессионалов» и даже «взрослых непрофессионалов». Во-вторых, «печеньки», возможно, должны восприниматься как маркер «тут меня будут холить и лелеять». «Мы будем специально стараться, чтобы вам спокойно кодилось, и ничего не отвлекало… даже в магазин бегать не придется». Возможно, кто-то подсознательно понимает это как «надо будет заниматься только разработкой в свое удовольствие, а всякое другое, что я делать не люблю, не хочу и не умею, возьмет на себя компания». В третьих, едва ли не большая часть когнитивных искажений связана с ошибками выбора и оценки. А в кадровой службе тоже могут работать «взрослые профессионалы», которые психологию знают и умело используют.
UFO landed and left these words here
+1
чем офис в зловонном подвале с табуретками, пентиумом три вместо компьютера и более высокую зарплату

Про «пентиумы» и «табуретки» как раз никто и не пишет, собственно в этом и проблема.
0
Это не ради мотивации. Просто модный мем, такой социальный пароль для «субкультуры», знак «мы тут в теме, знаем про кукисы».

Никому на самом деле печеньки не нужны, это просто такой опознавательный знак.
+1
Это они думают, что в теме. Про эти печеньки пишут все, и от этого уже тошнит не меньше, чем от «работа по ТК РФ». Как может быть паролем то, что знают все, непонятно.
+1
Вот да. Это было смешно и забавно сколько, 5 лет назад, больше? По меркам интернет мемов это древенее античности и лежит примерно на той же полке что и падонкавский сленг.
+1
Это подмена понятий. «В каждой вакансии пишут про X(печеньки), но не описывают рабочее место, следовательно писать про Х — плохо. » Это неправильно, правильно «Не описывать рабочее место — плохо». Короче говоря, оставьте печеньки в покое)
+2
Давайте писать «у нас в офисе электричество есть и зимой тепло»
+2
и зимой тепло

А давайте. Не приходилось в офисе сидеть в пуховике?
+3

Ох, очень хотелось бы видеть в вакансиях фразы типа "у нас в офисе нормальная приточная вентиляция и уровень ppm" и "у нас не приняты громкие дебаты и оффтоп в опенспейсе". Вот реально, дал бы скидку 10-20% зарплаты за эти два пункта.

0
Давайте писать «официальное трудоустройство» и «работа по ТК РФ». Хотя подождите…
0
Автор написал о том, что в вакансиях очень часто есть упоминание про печеньки. Я тоже это постоянно вижу и меня тоже это выводит из равновесия.

Так вот для кого safe spaces придумали! :)
+1
Чего?
Забавный чувак, открытым текстом говорит: «что бы иметь хорошие отношения с людьми нужно больше лести и лицемерия, главное делать это правильно и я расскажу вам как!»
+82
Опять уволили за токсичность? Сочувствую, тоже бывало. А теперь по пунктам:

1.
Почему-то активно продвигается мнение, что нельзя критиковать людей, нельзя вообще высказвать им негативную оценку.

Не соответствует правде. Критика постоянно высказывается, особенно в пулл-реквестах, после работы QA, и пользователями. Я бы сказал большая часть работы программиста — это работа с конструктивной критикой

2.
Человек может раз за разом отправлять вам на ревью код с одними и теми же ошибками и надо отвечать на это вежливостью и улыбкой?

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

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

Конечно же без явных причин! Токсичность и отсутствие компетенций тут не причем, да :)

4.
С годом опыта можно быть специалистом высшего уровня в профессии.

А когда, например, ява программист с 10 летним опытом, 5 из которых на управленческих позициях, начинает писать на PHP. Считаете, у за год не сможет до сеньора дойти? Ну считайте, ваше право :)

5.
Неожиданный факт — программисты не хотят работать без печенек.

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

6.
Через три месяца разговор с HR, в результате которого выясняется, что команда его ненавидит.

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

После прочтения данного произведения хотелось бы посоветовать автору перестать мыслить чрезмерно категоричными понятиями (ненависть, двуличие, подковерные интриги), и начать прислушиваться не только к своему мнению, но и к мнению окружающих, а так же хорошо выполнять свою работу, и тогда за токсичность никто уже увольнять не будет :)
-1
У всех свой опыт. Спасибо что поделились вашим. Однако, я не считаю себя абсолютно правым, в тексте много гиперболизаций.
Тут такое дело, нельзя всех причесать под одну гребёнку. А статью стоит рассматривать с юмором а не как крик души отчаявшегося грубияна.
+1
> Не соответствует правде. Критика постоянно высказывается, особенно в пулл-реквестах, после работы QA, и пользователями. Я бы сказал большая часть работы программиста — это работа с конструктивной критикой

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

В нетоксичных рабочих средах недопустима даже конструктивная критика личности человека, даже по его явной просьбе. Результаты работы, поведение в рабочих процессах — да, если конструктивно, то можно критиковать. Личность, поведение вне рабочих процессов — нет, даже конструктивно, по крайней мере в рамках работы — могут быть нюансы если общение не ограничивается рабочими процессами, но тут всё индивидуально.
0
недопустима даже конструктивная критика личности человека

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

Критикуйте то, в чем у вас есть набор компетенций. Если вы программист — профессионально критикуйте код, а для профессиональной критики личности есть психологи и психотерапевты, и их этому минимум 10 лет учат.

И это элементарное уважение к человеку как к личности, «нетоксичность» тут вообще не при чем.
0
Зачем может в принципе понадобится критика личности человека на рабочем месте? Если вы вы с коллегой приятели, можете обсуждать ваши личные дела, если это работе не мешает, но это к работе не имеет никакого отношения.
0
Есть люди, которые не могут не критиковать личность человека при критике его работы или её результатов. Ну типа «Ты это сделал? Идиот, переделывай!!!»
0
Критика постоянно высказывается, особенно в пулл-реквестах, после работы QA, и пользователями.

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


Вежливостью — да, улыбкой — нет. А потом просто вежливо попросить написать по собственному.

А если это не в вашей компетенции? Причем ответственный за проект ты, но задачи раздает и принимает начальник по принципу "работает — и ладно". Если человек коммитит код на Java в 201x году, где коллекции итерируются: for (int i = 0; i < list.size(); i++) list.get(i). А на просьбу переписать как надо жалуется начальнику, что я придираюсь. И кто тут разводит токсичность?


Ненависть коллектива сложно игнорировать, хочу я вам сказать.

Как показывает практика, ненависть и шум в основном разводят хреновые специалисты, как попытку оправдаться. И она всегда направлена против тех, кто в проекте что-то делает ввиде жалоб типа: "он придирается к моей работе", "он не объясняет мне как делать", "он не делится информацией", "он меня ничему не учит". HR, апелируя к жалобам, в итоге в токсичном поведении винят совсем других людей. Поэтому автор здесь прав — IT не детский сад, а спецы не няньки. Если человек некомпетентен, он баласт в проекте и будет только ухудшать климат и портить проект.

+1
Причем ответственный за проект ты, но задачи раздает и принимает начальник по принципу «работает — и ладно»

Если начальник раздает и принимает таски, то ответственный не вы, а начальник. В данной ситуации я обычно огораживаюсь от человека, который делает дичь. И не только я, прошу заметить. В результате с человеком никто не хочет работать, через месяц составляется отчет, и по результату безделия человека просят уйти. Именно про такую «ненависть» я говорю.
Про личностей, которых вы упомянули, а именно
ненависть и шум в основном разводят хреновые специалисты, как попытку оправдаться
— тоже регулируются подобным образом. Со скандалистами соглашаются работать такие же скандалисты, а результат такой команды редко выходит хороший. Ну и дальше по накатанной — пустой отчет — по собственному или по статье :)
0
Ответственный тот, кто согласился быть ответственным. При этом полномочий и даже других разумных возможностей на что-то влиять в процессе, за который ответственен, может и не иметь.
+1
Ответственный тот, кто согласился быть ответственным.

Это идеальный козел отпущения. Можно делать любую дичь, все равно вину свалят на того, кто согласился. Ответственности без полномочий не бывает, иначе это просто создание мальчика для битья
+1

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

+2
В данной ситуации я обычно огораживаюсь от человека, который делает дичь.

Отгородиться не удастся, ибо код и проект общий. А таск разбираться с любой проблемой на продакшне поставят тебе, ибо "ты есть лид" и ответственный. Вот и ловишь потом ликинги ресурсов и памяти в коде, к которому ты не имеешь никакого отношения и разбираешься с проблемой падений или проседания перформанса. А по завершении говорят "спасибо" и закрывают таск без всякого разбора полетов (а зачем, все ведь заработало, проблема решена, какая разница кто виноват — мы же все в одной команде?!).


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

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

+1
ты есть лид

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

Не успеешь моргнуть, как они уже начинают тобой командовать

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

А по завершении говорят «спасибо» и закрывают таск без всякого разбора полетов

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

какая разница кто виноват

А действительно, кто виноват? Разработчик, написавший гавно, тимлид, пропустивший это в продакшен, тестировщик не увидевший это на тестах, или, может, ПМ, эту задачу поставивший и обозначив недостаточный срок реализации? Кто из них виноват? Или может все вместе накосячили, одной командой?

0
А может и вины ничьей нет. Так сложились обстоятельства.
0
for (int i = 0; i < list.size(); i++) list.get(i)

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

0
Если человек коммитит код на Java в 201x году, где коллекции итерируются: for (int i = 0; i < list.size(); i++) list.get(i)

А что в этом плохого-то? То, что метод size() вызывается каждый раз, и это ухудшает производительность? А разве JVM то не оптимизирует в рантайме?
0
То есть вас только вызов «size()» здесь смущает? Ни вызов «get(i)» (который, вообще-то, может работать за линейное время), ни то, что уже в Java 5 можно было не отвлекаться на индексы
for (E e : list) {...}
.
-1
А вам не кажется, что у вашего варианта читаемость сильно ниже при беглом просмотре кода? Или это у меня только такое, субъективное?

Насчёт линейного времени — зависит от того, что за коллекция. Там может быть ArrayList или Vector, и там время доступа будет константное (но мы можем не знать, что у нас там на самом деле, т.к. интерфейс единый). При маленьких объёмах данных — это вообще, имхо, не суть важно.

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

P.S. Самое главное — я не понимаю, почему для вас стандартный заголовок цикла for(), который, кстати, одинаков вообще для любого C-подобного языка — это «отвлекаться на индексы». Такое вообще пишется (или вставляется по хоткею) на уровне автоматизма… Вот производительность кода — это да, серьёзно.
0
А вам не кажется, что у вашего варианта читаемость сильно ниже при беглом просмотре кода? Или это у меня только такое, субъективное?

Я, конечно, не s-kozlov, но нет, не кажется. Оно, как раз-таки сильно проще и приятнее. Меньше лишнего кода, меньше возможностей для выстрела себе же в голову.

P.S. Самое главное — я не понимаю, почему для вас стандартный заголовок цикла for(), который, кстати, одинаков вообще для любого C-подобного языка — это «отвлекаться на индексы».

Если человек не совсем дуб, то при итерации он в самом начале выделит элемент коллекции в переменную, аля var test = testList.get(i); В таком случае встреча индекса и использование коллекции в дальнейшем коде будет означать что-то специфическое. И, в целом, отвлечения на индексы особо не будет(но тут возникает вопрос — зачем? Зачем вручную прописывать создание переменной и использовать for(;;) конструкцию, когда есть более лаконичный foreach?)

А если человек дуб, то он просто везде будет использовать testList.get(i), что увеличит объём кода, уменьшит его читаемость и увеличит шансы случайно пропустить выстрел или логическую ошибку в виде testList.get(j) или testList.get(i-j)

Как по-мне, итерацию через индексы лучше делать только в том случае, если есть необходимость оперировать этими индексами. Не вижу смысла пихать такую итерацию куда попало, когда в языке есть куда более подходящие конструкции.
0
Зачем вручную прописывать создание переменной и использовать for(;;) конструкцию, когда есть более лаконичный foreach?)

Чтобы не создавать итераторы.

0
Создать один итератор (константная, притом мизерная, память и практически константное и опять же мизерное время) или превратить линейное время итерации в квадратичное, попутно изговнякав код? Это уже даже не смешно.
0
Квадратичным оно станет только в случае с настоящим списком (LinkedList, например). Если быть совсем точным — там будет O(n² / 2). В случае с тем же Vector всё будет линейно.
+1
В случае с тем же Vector всё будет линейно.

У меня маленькое замечание не относящееся к делу прямо. Класс Vector остался в джаве только потому, что нельзя ломать спецификацию. Он — тяжёлое наследие прошлого. Использовать его нельзя.

-1
Что за глупости? Только его обычно и используют, когда нужен динамический массив с изменяемой длиной.

Что касается ArrayList — он как бы есть, но он ничем не лучше. К тому же, он не является потокобезопасным.
+1
Что за глупости? Только его обычно и используют, когда нужен динамический массив с изменяемой длиной.

Это не глупости, это суровая реальность. Если пишешь на Java и нужен динамический массив — нужно использовать ArrayList.


Что касается ArrayList — он как бы есть, но он ничем не лучше. К тому же, он не является потокобезопасным.

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


Если нужна потокобезопасность Vector тоже плохой выбор. Нужно использовать либо обёртки, которые делают любую коллекцию потокобезопасной, такие как Collections.synchronizedList, либо использовать специализированные коллеции, такие как CopyOnWriteArrayList.

-1
приводит к синхронизации потоков

В том-то и дело, что обычный код, как правило (могу ошибаться, поправьте) исполняется всегда в один поток (кроме обработки GUI). А раз так — ему пофиг, что использовать. Если же приложение многопоточное — всё равно нужна синхронизация будет, скорее всего.

Если нужна потокобезопасность Vector тоже плохой выбор. Нужно использовать либо обёртки, которые делают любую коллекцию потокобезопасной, такие как Collections.synchronizedList, либо использовать специализированные коллеции, такие как CopyOnWriteArrayList

А чем они лучше Vector?
+1
В том-то и дело, что обычный код, как правило (могу ошибаться, поправьте) исполняется всегда в один поток (кроме обработки GUI). А раз так — ему пофиг, что использовать.

Даже если код выполняется в один поток — вся машинерия, которая синхронизирует потоки всё равно отрабатывает честно и честно жрёт время процессора. Поэтому нет, не пофиг. ArrayList эту машинерию не задействует вообще, поэтому он быстрее. Разработчики JDK рекомендуют использовать ArrayList там, где потокобезопасность не нужна. Так и написано — If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.


А чем они лучше Vector?

Обёртки делают практически то же самое, что Vector. CopyOnWriteArrayList обеспечивает потокобезопасность тем, что делает новую копию внутреннего массива при каждом изменении. Его надо использовать если коллекцию в основном читают и иногда в неё что-то пишут.

0
Прочитал про эти обёртки по Вашей ссылке. Но неужели копирование при каждом изменении — это быстро?.. Всё равно же накладные расходы огромны. Чем это лучше использования Vector?
+1

Вариант Vector:
1 поток на запись, 20 потоков на чтение — стопаем всех при каждом обращении к вектору,
Вариант CopyOnWriteArrayList:
1 поток на запись, 20 потоков на чтение: да потоки на чтение могут получить устаревшую информацию, но они всегда могут прочитать из массива без остановки, блокируют ли друг друга потоки на запись — не помню, надо смотреть спеку.
В общем для ситуации "в основном читаем, изредка пишем" идеальная коллекция.


И да, в промышленной разработке про вектор, к счастью, уже забыли.
Если хотите подробности про мягкие блокировки и какие они плюсы дают — поищите по вкладу Doug Lea в java — он как раз их и разработал для java.


Смотрите, foreach подразумевает то, что о типе итерируемой сущности позаботится рантайм (или компилятор). В случае с JavaScript (я в основном пишу на нём), использование for… in, перебирающего все ключи объекта либо индексы массива — реально очень плохая идея, если у нас обычный массив. for всегда будет быстрее. JS правда, в отличие от Java, не компилируется в байт-код в общем случае (точнее, компилируется в него прямо перед исполнением, и время этой компиляции нам тоже важно).

Ох, юноша, ну куда же вы со своим js в обсуждение java? Ведь надо понимать, что и структуры и алгоритмы под капотом синтаксического сахара сильно разные. В Java foreach это скрытый вызов итератор и обход по нему. И не надо думать, что если в js есть слово java, то они хоть чем-то похожи.


Кстати, на минутку — есть какой-то аргумент, чем итератор лучше цикла for? Тем, что он сохраняет стейт коллекции в момент начала обхода? Так он ничего не сохраняет, там при попытке изменения коллекции исключение выкинет…

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


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

Початайте Кнута, дельные вещи мужик написал. Ещё можете почитать/посмотреть доклады про оптимизации Шипилёва — очень доходчиво рассказывает про трудозатраты vs результаты оптимизаций. Не помню только, говорил ли он, что новичкам в языке лучше вообще не связываться с оптимизацией… Там ведь надо уже понимать как jvm твой код обработает и во что превратит…
В общем случае лучше писать правильный/красивый код, а оптимизации оставить на горячие участки, которые реально нужно ускорять.


Кстати, забыл добавить: выше комментаторы указывали, что создание итератора — это лишние накладные расходы, и в некоторых случаях они могут быть существенными. Тогда зачем использовать foreach вместо for (то, что это сахар — уже замедлит компиляцию в байт-код как минимум на копейки, плюс само наличие итератора, которое может быть нежелательным)? Не говорите только опять про опечатки в буквах, такие ошибки — это даже не уровень школы, серьёзный программист никогда их не допустит (да и IDE не даст).

Нет, создание итератора — не очень дорогая операция и если не жарить её миллионы раз на одной коллекции худо от них не будет точно. Время компиляции в java так же в большинстве случаев пренебрежимо мало и происходит один раз — при сборке пакетов (ну разработчик пару наносекунд подождёт, чего уж там, ага?). Худшее что я видел — пара минут на дофига кода. Гораздо хуже какой-нибудь gwt, который из 1-2к строк будет минуты 3 комплиться. Для кого долго — пусть покомпилят программы на c/c++.
Про опечатки — это хлеб стат. анализаторов и это первое чему они учатся. Да сейчас их встраивают в IDE, но онлайновые всё же далеки от совершенства. И да, даже с ними можно пролететь с опечаткой. Почитайте тематические статьи, если интересно. Но на исходниках > 10к "рассмотреть всё глазками" не работает почти никогда.


С последним утверждением — полностью согласен. Проблема в том, что цикл for — это не «фишка» только JavaScript. Такие циклы можно встретить и в программах на C, C++, ActionScript и PHP, как минимум. То есть это общепринятая конструкция. Да, в Java могут быть лучшие способы итерирования, и не только в Java. Но писать код, понятный программисту на любом языке — имхо, не есть минус…

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


PS простите за комментари n-in-1, минусы отрицательной кармы при недостатке писательских навыков :-)

0
В общем для ситуации «в основном читаем, изредка пишем» идеальная коллекция.

Согласен. А если у меня вообще поток всего один, и никто никого не блокирует? Можно ещё раз на пальцах, чем Vector медленнее ArrayList в случае одного потока?

И не надо думать, что если в js есть слово java, то они хоть чем-то похожи.

Я так и не думал, вы что.

В Java foreach это скрытый вызов итератор и обход по нему.

Окей, я про это выше уже читал. Создание итератора — в самом деле лишние накладные расходы, которых можно избежать. Зачем нам итератор? От него выигрыш только в случае использования LinkedList. Но если мы решим его использовать, то и несколько циклов в этот момент можно будет переписать, которые с ним работают. В чём проблема-то?

Итератор не сохраняет состояние, он отказывается работать с изменённой коллекцией.

И что тут хорошего? Ошибка в консоль, вылет из метода по не пойманному исключению, программа у пользователя «упала». Может лучше всё-таки отработать с чуть устаревшими данными? А ещё лучше — ещё на этапе написания кода подумать о том, что будет, если коллекцию кто-то попытается изменить. И вот здесь как раз пригодится CopyOnWriteArrayList, о котором Вы выше упоминали. Или можно самому вручную создать копию коллекции, и обходить уже её (в противном случае мы вылетим с ошибкой, если у нас итератор!).

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

Соглашусь :) Именно поэтому я особо и не заморачиваюсь с быстродействием своего Java кода. Ну хотя наверное я начну это делать, только когда всё очень сильно начнёт тормозить…

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

Так никто и не спорит! Там же выше шла дискуссия о том, нужно ли использовать итератор, если он даёт оверхед. Моё мнение — если можно на этом сэкономить, то не стоит: обход по индексам, в случае, если соблюдены все меры предосторожности, даст тот же эффект в случае не списка.

ну разработчик пару наносекунд подождёт, чего уж там, ага?

Да Вы оптимист! У меня не самый большой курсовой проект комплилися на среднем железе (окей, на довольно слабом железе для тех лет) секунд 7-8. Это простой проект. А если что-то тяжёлое? Тут и 1-2 секунды можно лишних получить, особенно если плохой HDD вместо SSD.

Для кого долго — пусть покомпилят программы на c/c++.

Я в курсе про время компиляции программ на C++. Вы правда считаете, что это хорошо? Я вот не понимаю, как люди вообще так живут и работают (в случае, если у них нет супербыстрого корпоративного билд-сервера, а обычный ноут).

Про опечатки — это хлеб стат. анализаторов и это первое чему они учатся. Да сейчас их встраивают в IDE, но онлайновые всё же далеки от совершенства.

Онлайновые — это какие? Там имели в виду случай, когда в заголовке или теле цикла перепутана буква итератора. Как минимум любая IDE подчеркнёт ошибку, если мы напишем j вместо i, а такой переменной у нас нет. Да, бывают случаи вложенных циклов, бывает, когда переменная j есть внутри тела цикла, и мы опечатались в каком-то индексе. Ну а отладка на что? Точки останова? Юнит-тесты, в конце концов? Обычное тестирование «руками» на нескольких наборах данных? Такая ошибка обычно всплывает на первом же прогоне!

Но на исходниках > 10к «рассмотреть всё глазками» не работает почти никогда.

Вы что, за раз добавляете и коммитите 10k строк? Нет, вы обычно добавляете строк 100-200, ну в крайнем случае 500. А длина одной функции вообще в идеале должна быть строк 40-50, не больше. И циклов там — ну максимум 2-3. К чему тут обсуждать общий размер кодовой базы проекта вообще?

Просто поймите, есть стандарты кодирования. Для каждого языка.

Опять Вы про что-то не то говорите. Стандарт кодирования — это скорее про правила оформления кода. Например, то, что в C# открывающая фигурная скобка класса переносится на новую строку, в отличие от Java. Это да, тут я не спорю, лучше делать так, как рекомендует разработчик языка (хотя даже это можно перенастроить в IDE под себя и делать по-своему — если работаешь не в команде, либо если ты возглавляешь команду и сам определяешь правила оформления кода). Но цикл for-то тут причём? Это вполне себе легитимная конструкция языка Java! Это не какой-нибудь goto, который кое-где ещё есть, но использовать его не советуют. Никто его использовать не запрещает, более того, он для этого изначально и был предназначен — для обхода массивов в том числе. Да, в Java он пришёл скорее всего как наследие из C/C++, но я не видел ещё ни одной статьи, которая утверждала бы, что «for в Java — это зло, по возможности никогда его не используйте».

PS простите за комментари n-in-1

Да нет проблем. Хотя отвечать и правда чуть проще было бы в случае нескольких комментариев поменьше. Но проблему вложенности это не решит, да и объём текста для ответа тоже не уменьшит, так что невелика беда :)
0
А если у меня вообще поток всего один, и никто никого не блокирует? Можно ещё раз на пальцах, чем Vector медленнее ArrayList в случае одного потока?

Случай с одним потоком это как раз тот случай, когда Vector всегда медленнее. Потому, что любой метод у Vector работает дольше, чем у ArrayList за счёт того, что на каждом методе Vector осуществляется синхронизация. Когда поток один, синхронизация не нужна, но время на неё всё равно уходит.

-1
Это да. Но насколько эта синхронизация замедляет работу? Можно какие-то бенчмарки найти? Ведь мы никого «не тормозим», по идее, раз один поток.
+1
Это да. Но насколько эта синхронизация замедляет работу?

На столько, что из-за этого замедления разработчики JDK и добавили ArrayList

-1
Мне бы в процентах. А лучше — в мс для типового сценария (для списков размеров не больше 100 элементов, например). Я просто не пишу программ, где требуется очень высокая производительность…
+1
Если вы пишете программы, которые будут читать другие разработчики на этом языке, то использовать Vector — дурной тон. Одного этого вам должно быть достаточно, чтобы не использовать его.

Если же вы пишете программы себе в ящик, которые никто, кроме вас и видеть не будет — вы вольны использовать, что пожелаете, но убеждать и спорить с людьми по поводу этого вам не стоит, выставляете себя лишь в плохом свете.
-1
Если вы пишете программы, которые будут читать другие разработчики на этом языке, то использовать Vector — дурной тон
Это с чего вдруг?.. Там интерфейс абсолютно такой же. Разница только в производительности — но каким боком связаны производительность выполнения и процесс чтения кода?
+1
Это с чего вдруг?..

Вам уже десяток людей сказала — потому что для обычных коллекций в большинстве случаев принято использовать ArrayList.
Почему? Потому что Vector медленнее и в большинстве случаев синхронизация излишняя.

Бенчмарки гуглятся за полторы минуты, будь у вас такое желание.
stackoverflow.com/questions/17471913/java-vector-vs-arraylist-performance-test
www.baeldung.com/java-arraylist-vs-vector

И суммарно, если вы будете использовать Vector, то вы будете этим показывать свой низкий уровень владения языком, поскольку в 95% случаев это будет не оправданным решением, а лишь потому что вы так привыкли и вам так удобнее.

И, помнится, вы так ратовали за то, что использование foreach накладывает оверхед и лучше обходиться простым for с индексацией. Раз вы так боретесь за оверхед, то почему же используете Vector, который его вносит? Не находите противоречие?
0
И суммарно, если вы будете использовать Vector, то вы будете этим показывать свой низкий уровень владения языком, поскольку в 95% случаев это будет не оправданным решением

Может и так. Я просто не понимаю вот этого вот «дурной тон», как-то очень категорично прозвучало. такое ощущение, что у вас прямо кровь из глаз льётся каждый раз, когда Вы слово «Vector» видите в коде. Несерьёзно как-то :)
+1
Я просто не понимаю вот этого вот «дурной тон», как-то очень категорично прозвучало. такое ощущение, что у вас прямо кровь из глаз льётся каждый раз, когда Вы слово «Vector» видите в коде.

Когда вы, в 2019 году будете писать стандартами 2000 года — это дурной тон. Крови из глаз не будет, однако наладить коммуникацию с коллегами вам будет куда сложнее.
Банально, видя ваши постоянные for и vector — на ревью к вам постоянно будут подходить и, скажем так, вбивать в голову — что так писать нельзя. Есть более подходящие инструменты.
Про veсtor и arrayList прекрасно написано тут, stackoverflow.com/questions/1386275/why-is-java-vector-and-stack-class-considered-obsolete-or-deprecated
Эта ссылка была в бенчмарке, который я кидал выше.

Несерьёзно как-то :)

И, если вы не измените своё мнение и стиль разработки после таких ревью, то коллеги просто не захотят с вами работать. Вы будете причиной негативной атмосферы в коллективе, которая ведёт к негативным последствиям для разработки продукта.
Если для вас это несерьёзно, то… что ж, ваш выбор.
0
Я просто не понимаю вот этого вот «дурной тон», как-то очень категорично прозвучало.

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


такое ощущение, что у вас прямо кровь из глаз льётся каждый раз, когда Вы слово «Vector» видите в коде.

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

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

Когда использовал его в первый раз — просто принципиально хотелось выпендриться и сделать не так, как в листингах, которые нам раздали. То есть попробовать что-то своё. Попробовал — получилось, интерфейс-то идентичный. Я там ещё и Hashtable вместо HashMap в одном месте заюзать умудрился. Один раз правда всего)

Чаще всего встречается заблуждение, что если используешь Vector, то с синхронизацией можно вообще не заморачиваться, он всё сделает.

Не всё. Нам в универе рассказывали, в чём нюанс, и в учебнике по Java было это написано. И я это помню прекрасно. Синхронизированы только отдельные операции, общую синхронизацию нужно обеспечивать самостоятельно.

На ревью, кстати, код с Vector не пропустят.

Почему? Производительность? Так не всегда она является узким место. Я вот смотрел сейчас бенчмарк, между прочим, там разница конечно в два раза, но пока это 7ms и 14ms, с этим жить можно.
+1
Когда использовал его в первый раз — просто принципиально хотелось выпендриться и сделать не так, как в листингах, которые нам раздали

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


Почему [Vector не пропустят на ревью]? Производительность? Так не всегда она является узким местом

Возможно когда-то такое не пропускали из-за производительности. Сейчас не пропустят по тем же причинам, по которым не пропускают плохо отформатированный код. Видим Vector — отправляем реквест на доработку.

-1
Возможно когда-то такое не пропускали из-за производительности.

Ещё раз — нам никто из преподов категорически не запрещал использовать векторы (хотя упоминали, что у них довольно плохо с производительностью). Это был 2010-ый год. Java SE 6, на минутку :)

по которым не пропускают плохо отформатированный код

А не проще его доформатировать и принять? Тем более, сейчас есть всякие линтеры и средства бьютификации.
+2
Ещё раз — нам никто из преподов категорически не запрещал использовать векторы

В IT с хорошими преподавателями серьёзная проблема. Те, кто разбирается в предмете редко занимаются преподавательской деятельностью, увы ((.


А не проще его доформатировать и принять?

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

0
Те, кто разбирается в предмете редко занимаются преподавательской деятельностью, увы

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

Предыдущий комментатор говорит про далёкость преподавателей (в том числе ваших аспирантов) от промышленной разработки. Это сказывается и сильно на том, какой и как они дают материал. И да, Vector нерекомендован к применению самими разработчиками java.


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

-1
Предыдущий комментатор говорит про далёкость преподавателей (в том числе ваших аспирантов) от промышленной разработки.

Я бы не сказал так. Тот парень в «ЛАНИТ-Теркоме» работал. Правда, его основной язык таки C++ :)

требования к лабам существенно ниже, чем требования к промышленным программам

В каком именно плане они ниже? Я бы не согласился.
Потом, лаба лабе рознь. У моей программы тысячи скачиваний только за первый год по всему миру, свои задачи она прекрасно выполняет.
+1

У него не просто основной язык c++, он в принципе работал(ет) в компании, которая занимается преимущественно разработкой на этом языке (ещё у них там есть мобильщики, ага… но это свой отдельный мир всё же).
В общем вопрос в том, что применять в java технологии c++… это по меньшей мере странно.


В каком именно плане они ниже? Я бы не согласился.
Потом, лаба лабе рознь. У моей программы тысячи скачиваний только за первый год по всему миру, свои задачи она прекрасно выполняет.

Привидите пример вашей лабы:


  • какие задачи решает?
  • насколько критична скорость/производительность/потребление?
  • что будет, если будет 100/1000/10000 и больше запросов в минут?
0
В общем вопрос в том, что применять в java технологии c++… это по меньшей мере странно.

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

Привидите пример вашей лабы

Ну, она не совсем лаба, а семестровая/курсовая, но не суть, не будем раздувать значимость :)

Визуализатор алгоритмов на графах. Задача — выполнять алгоритмы, подсвечивая в риалтайме состояние рёбер и вершин, вести логи операций. Есть встроенный редактор графов и удалённое хранение на сервере даже (не помню уже, зачем это делал). Соответственно, есть сервер под это дело в виде отдельной утилиты (с GUI). Он тоже использует векторы. Но я никогда не проводил нагрузочного тестирования всего этого. Скажем так, 1 клиент с 8-10 запросами в секунду (всего порядка 25-30 запросов, передача данных построчно в текстовом формате без использования даже HTTP протокола) — это не нагрузка.
0
Но меня он за код с векторами по рукам не бил, я вот о чём. Просто всех призывал учитывать, когда что лучше применять (в том числе учитывая то, нужна ли многопоточность).

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


Визуализатор алгоритмов на графах. ...

Т.е. получаем:


  • нагрузка низкая (вектор не в силах дать визуально-заметный лаг),
  • производительность, как я понимаю, особая не нужна?
  • потребление по памяти скорее всего можно поигнорировать (есть подозрение, что jvm у вас кушает больше, чем ваша программа)?
  • а что за сервер, не подскажете (какие библиотеки, протокол, ...)?
0
ибо он многие проблемы решить не способен, но вызывает ложное ощущение защищённости
Примерно в таких формулировках нам вроде и не советовали его использовать, Вы правы. Я похоже и правда что-то подзабыл.

есть подозрение, что jvm у вас кушает больше, чем ваша программа
Не исключаю, что так и есть :)

а что за сервер, не подскажете (какие библиотеки, протокол, ...)?
Никаких библиотек. Текстовый протокол собственного сочинения, обмен через сокеты. И я прекрасно помню, там была проблема нарушения порядка прохождения отдельных запросов (отправляем 1, 2, 3, ..., 10, приходит 3, 4, 1, 6, 5, ...). Я не знал, как пофиксить это по уму, поэтому просто ввёл в протокол нумерацию строк. Кстати, новый коннекшен на каждую строку не делался, просто шла запись в стандартный PrintWriter через println. Могу покопаться в коде и посмотреть, как там было сделано.
+1
Ну у нас по практике преподы были молодые (аспирант по сути). Так что книжки они читали тоже довольно новые, на возраст тут не спишешь.

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


Мне всё-таки кажется, это Вы излишне категоричны в суждениях.

Я категоричен, но не излишне.


То, что вектор неоптимальный вариант и более медленное решение — не мешает его применять

Именно это и мешает.


и получать работающий, и даже не глючащий продукт

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


Опять же — я применял его столько лет

Самое время перестать ))


и не разу не получил ни одной проблемы (с производительностью в том числе).

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

-1
Я категоричен, но не излишне.

Категоричность — это плохо :)

Именно это и мешает.

Нисколько. Ваша позиция сейчас напоминает позицию человека, который призывал бы использовать ассемблер вместо C/C++, потому что «так быстрее работает и легче контролировать результат».

Самое время перестать ))

С чего вдруг? Работает же. И даже если его «выпилят» в будущих версиях JVM совсем — те проекты, которые я писал под Java 1.6, так и останутся работать под 1.6 (в крайнем случае, под 1.7). Так что даже это не проблема.

Проблем на код ревью у вас не было либо потому, что не было код ревью

Да, их не было. Было тестирование собственными силами, чтобы понять, есть ли ошибки, и достаточно ли всё оптимально работает. В том числе и в плане скорости.

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

Браво, вы наконец-то это поняли. Так зачем тогда там что-то переписывать, раз она не критична?)
+1
Нисколько. Ваша позиция сейчас напоминает позицию человека, который призывал бы использовать ассемблер вместо C/C++, потому что «так быстрее работает и легче контролировать результат».

Если бы ассемблер и C/C++ ничем, кроме названия не отличались, ваша аналогия была бы хорошей. В данном случае она плохая.


Так зачем тогда там что-то переписывать, раз она [производительность] не критична?)

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

0
просто, чтобы не было стыдно за свой код
Я больше всего не согласен вот с этим. Не понимаю, почему за код с Vector должно быть стыдно, если он работает корректно и не тормозит.
0
Это с чего вдруг?.. Там интерфейс абсолютно такой же.

Что интересно, и у LinkedList точно такой же интерфейс.


Разница только в производительности

И с LinkedList у ArrayList разница в производительности и ещё в количестве используемой памяти. Но с процессом чтения кода это не связано никак.


Готовы ли вы воспользоваться своей же логикой, чтобы оправдать использование LinkedList там, где все используют ArrayList?

-1
Что интересно, и у LinkedList точно такой же интерфейс.

И это хорошо. Специально же так спроектировано.

Готовы ли вы воспользоваться своей же логикой, чтобы оправдать использование LinkedList там, где все используют ArrayList?

Между этими двумя коллекциями разница ещё меньше. Только вот час назад читал отличный вопрос на STO на эту тему :)

По сути, зависит от того, что нам нужно делать чаще: удаление/вставку или доступ к произвольному элементу (да, вставка в LinkedList тоже побыстрее, поиск по нему в среднем N/4, а в случае с ArrayList нам нужно делать сдвиг хвоста, и там в среднем N/2). В плане обхода — вообще без разницы. Оверхед по памяти — есть, но крайне мал, и чем меньше список, тем он меньше в абсолютном значении.

В моём коде, который я писал для браузерного движка, прямой доступ к элементу по номеру почти никогда не используется. Там везде только обходы, поэтому что именно использовать — там почти всё равно (не считая оверхеда по памяти у LinkedList).
+1
Между этими двумя коллекциями разница ещё меньше.

Разница между LinkedList и ArrayList огромна.


В плане обхода — вообще без разницы.

Разница большая, LinkedList не ложится в кеш.


Оверхед по памяти — есть, но крайне мал

LinkedList занимает в памяти где-то в 6 раз больше места, чем ArrayList.


Там везде только обходы, поэтому что именно использовать — там почти всё равно

Так как там только обходы — использовать можно только ArrayList.


P. S. Прошу прощеня за краткость, стараюсь писать только главное. Работа ))

-1
Разница между LinkedList и ArrayList огромна.

Не так и огромна. Посмотрите сами сравнения:
stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist-in-java

LinkedList занимает в памяти где-то в 6 раз больше места, чем ArrayList.

Простите, «лолшто»? Там оверхед в в два указателя на каждый элемент списка, и всё. Вы разве не в курсе, что память под указатель имеет постоянный размер независимо от типа (и количества полей и методов в классе, на который мы ссылаемся)?

Ссылка на объект или массив занимает одно 32-битное слово (4 байта) на 32-битной виртуальной машине JVM или Davlik. A null занимает то же место, что и ссылка. (Он должен, потому что нуль должен быть помещен в слот с типизированным типом, то есть поле экземпляра, локальную переменную и т.д.)

С другой стороны, объект занимает минимум 2 32-битных слова (8 байтов), а массив занимает минимум 3 32-битных слова (12 байтов). Фактический размер зависит от количества и типов полей для объекта, а также от количества и типов элементов для массива.

Для 64-разрядной JVM размер ссылки составляет 64 бита, если вы не настроили JVM на использование сжатых указателей.
0
Не так и огромна. Посмотрите сами сравнения:

Сравнение неполное, но даже там с самого начала написано, что почти всегда надо использовать ArrayList. В комментарии, кстати, есть уточнение про кеш.


Простите, «лолшто»?

"лолLinkedListбольшеArrayListгде-тов6раз" ))


Там оверхед в в два указателя на каждый элемент списка, и всё.

Ну, то есть по вашему мнению LinkedList занимает всего в 3 раза больше, чем ArrayList?


Вы разве не в курсе, что память под указатель имеет постоянный размер независимо от типа (и количества полей и методов в классе, на который мы ссылаемся)?

Ладно, шутки в сторону. В ArrayList на один элемент приходится 1 указатель на объект, то есть 8 байт. В LinkedList — указатель на объект — 8 байт, указатель на следующую ноду — 8 байт, указатель на предыдущую ноду — 8 байт, оверхед на объект с нодой — 16 байт.


Это у нас получает разница в 5 раз. По умолчанию в джаве включена компрессия указателей. Тогда на указатель приходится 4 байта и разница получается не в 5, а в 7 раз. Плюс могут быть различия в зависимости от конкретной реализации JVM. Такие дела.

0
А если у меня вообще поток всего один, и никто никого не блокирует? Можно ещё раз на пальцах, чем Vector медленнее ArrayList в случае одного потока?

На примере извлечение элемента i:
ArrayList:
Операция 1: берём указатель на внутренний массив (лёгкая операция в малое количество циклов)
Операция 2: извлекаем из массива элемент i (лёгкая операция в малое количество циклов)
Vector:
Операция 1: Входим в монитор (тяжёлая операция в существенно большее количество циклов)
Операция 2: Получаем указатель на внутренний массив (лёгкая операция в малое количество циклов)
Операция 3: Извлекаем элемент i из массива (лёгкая операция в малое количество циклов)
Операция 4: Освобождаем монитор (не помню точно, насчёт сложности операции)
Вот и посчитайте, что выполнится быстрее. Пример приведён исключительно для однопоточного приложения. Для многопоточного доступа (если у нас только чтение — то можно же и из ArrayList-а читать) там будут ещё нюансы, что читает одновременно только один поток, а остальные тупо стоят ждут.


Создание итератора — в самом деле лишние накладные расходы, которых можно избежать. Зачем нам итератор? От него выигрыш только в случае использования LinkedList. Но если мы решим его использовать, то и несколько циклов в этот момент можно будет переписать, которые с ним работают. В чём проблема-то?

Потому что, чем меньше мест где можно накосячить — тем меньше багов в программе. Foreach не даёт возможности накосячить, for через интовый итератор — только в путь. При этом проигрышь по производительности от итератора в большинстве случаев не ощущается от слова никак. А вот там, где ощутили — там и нужна оптимизация. В общем code convention — они не просто так придуманы.


И что тут хорошего? Ошибка в консоль, вылет из метода по не пойманному исключению, программа у пользователя «упала». Может лучше всё-таки отработать с чуть устаревшими данными?

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


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

Ну вы неужели думаете, что баги пишутся сознательно? Половина багов возникает по невнимательности, вторая половина — при изменении изменении зависимого/зависящего от этого куска кода. Ну просто меняются условия работы и там, где код использовался в одни поток вдруг появляется несколько потоков.


Так никто и не спорит! Там же выше шла дискуссия о том, нужно ли использовать итератор, если он даёт оверхед. Моё мнение — если можно на этом сэкономить, то не стоит: обход по индексам, в случае, если соблюдены все меры предосторожности, даст тот же эффект в случае не списка.

Ещё раз — да оверхед по стоимости выполнения (копеечный в общем-то — и по памяти и по процессору), который обеспечивает уменьшение мест для появления багов. Право слово — оно того стоит в 99% ситуаций.


Да Вы оптимист! У меня не самый большой курсовой проект комплилися на среднем железе (окей, на довольно слабом железе для тех лет) секунд 7-8. Это простой проект. А если что-то тяжёлое? Тут и 1-2 секунды можно лишних получить, особенно если плохой HDD вместо SSD.

В java как-то принято в модульность. Реально проектов на 100 тысяч строк и больше не так уж и много, но даже эти проекты собираются за пару минут. Вот тесты могут крутиться уже существенно дольше. И я говорил про оверхед от единичного использования синтаксического сахара.


Онлайновые — это какие?

Онлайновые — это которые IDE запускает во время написания кода и/или простоя самостоятельно.


Там имели в виду случай, когда в заголовке или теле цикла перепутана буква итератора. Как минимум любая IDE подчеркнёт ошибку, если мы напишем j вместо i, а такой переменной у нас нет.

А если такая переменная есть?


Да, бывают случаи вложенных циклов, бывает, когда переменная j есть внутри тела цикла, и мы опечатались в каком-то индексе. Ну а отладка на что? Точки останова? Юнит-тесты, в конце концов? Обычное тестирование «руками» на нескольких наборах данных? Такая ошибка обычно всплывает на первом же прогоне!

Простите, вы собираетесь каждый кусок кода вручную тестировать? Иначе зачем вам эти самые "отладка" и "точки останова"? Нет на это времени практически никогда. К такому способу тестирования прибегают в 2х случаях: есть бага, но не до конца понятно, в какой момент алгоритм лажает, или код совсем уж труднотестируем автоматически — так вручную на паре-тройке наборов прогоняется… Юнит-тесты… Вы слышали о 100% покрытии не в TDD? А большинство работает не по TDD. А вы в курсе, что реально все случае проверить нереально, именно поэтому появилась такая штука как "мутационное тестирование"? В общем способов-то обезопаситься много… но вот foreach реально тупо дешевле. Его использования занимает условно секунду, а тесты/юнит-тесты/прочие радости — минуты, часы, ...


Вы что, за раз добавляете и коммитите 10k строк? Нет, вы обычно добавляете строк 100-200, ну в крайнем случае 500. А длина одной функции вообще в идеале должна быть строк 40-50, не больше. И циклов там — ну максимум 2-3. К чему тут обсуждать общий размер кодовой базы проекта вообще?

Ну бывает, что и по 2к строк за раз в коммит уходит, пусть и крайне редко… Средний коммит, да — 100-400 строк. А длина функции больше 10 строк — это уже сигнал внимательно на неё посмотреть и по возможности разбить… Вот только как всегда, есть нюанс: баги привносятся чаще всего не в том месте, которое изменяют, а в те места, которые от него зависят. И чем больше кодовая база, тем больше случаев взаимного использования разных кусков кода. А опечатки "замыленый" глаз банально не видит даже в 10 строчках (проверено неоднократно).


Опять Вы про что-то не то говорите. Стандарт кодирования — это скорее про правила оформления кода.

Вы не поверите, но использование (или не использование) синтаксического сахара — это тоже часть стандартов кодирования.


Но цикл for-то тут причём? Это вполне себе легитимная конструкция языка Java!

Ну так кто же заставляет от цикла-то отказываться? Только вот количество возможных вариантов его использования снижаются сознательно — выше уже неоднократно писал почему


Это не какой-нибудь goto, который кое-где ещё есть, но использовать его не советуют.

Вот 90% говорящих про вред goto никогда не пользовались goto. В грамотных руках — отличнейшая инструкция… а в ассемблере — так и вовсе никуда без неё.


Никто его использовать не запрещает, более того, он для этого изначально и был предназначен — для обхода массивов в том числе.

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


Да, в Java он пришёл скорее всего как наследие из C/C++, но я не видел ещё ни одной статьи, которая утверждала бы, что «for в Java — это зло, по возможности никогда его не используйте».

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

0
Входим в монитор (тяжёлая операция в существенно большее количество циклов)

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

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

Так я ж писал — нельзя серьёзный алгоритм (который может привести к серьёзным проблемам из-за багов) пихать в прод, толком не протестив. Особенно если программа многопоточная. Сначала юнит-тесты хотя бы сделать и прогнать надо… И даже с точки зрения самого алгоритма — ваш подход не решит проблему, а только сделает её более явной и заметной. А чтобы её решить, надо сам код переписывать. например, перед обходом коллекции делать копию, как я предложил выше.

Половина багов возникает по невнимательности, вторая половина — при изменении изменении зависимого/зависящего от этого куска кода.

За первое надо по рукам бить, второе — пытаться поймать на тестах. Ну или смириться с багами, которые вылезут потом :)

И я говорил про оверхед от единичного использования синтаксического сахара.

Только мест, где Вы будете его использовать, намного больше одного. И да, я вполне представляю проект, которые даже на сегодняшнем железе будет собираться в районе минуты (раз мой собирался 8 секунд при своём малом размере). Наверное, таких проектов даже немало.

А вы в курсе, что реально все случае проверить нереально, именно поэтому появилась такая штука как «мутационное тестирование»?

Все — не реально, но все имхо как правило проверять и нет необходимости. Про мутационное тестирование увы не читал :)

К такому способу тестирования прибегают в 2х случаях: есть бага, но не до конца понятно, в какой момент алгоритм лажает, или код совсем уж труднотестируем автоматически — так вручную на паре-тройке наборов прогоняется…

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

А длина функции больше 10 строк — это уже сигнал внимательно на неё посмотреть и по возможности разбить…

Вы говорите прямо как нас в вузе учили… Да вот только жаль у меня пока не выходит таких коротких функций в реальных проектах, даже там, где логика очень простая :) Примерно 25-30 строк получается.

В грамотных руках — отличнейшая инструкция…

Да-да, нам так же говорили. Я вроде бы даже видел её где-то в исходниках JDK, кажется. Сам лично правда не использовал, не довелось как-то :)

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

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

Ну и напоследок. Мне вот очень приятно и привычно видеть обход любой коллекции глазами в коде как for и буковки i (ну привычка такая за много лет сформировалась уже). Использование итератора в чистом виде подразумевает или использование while (и одна доп. строка сверху для создания итератора), или использование for без третьего выражения

for (Iterator it = list.iterator(); it.hasNext(); ) 

Слава богу, конечно, что есть вариант с foreach, это реально позволяет не использовать while и не добавлять лишние строки в код над циклом.
0
Но я не знаю абсолютно, как в Java устроены мониторы. Надо бы почитать. Просто может ведь оказаться, что не такая уж это страшно тяжёлая операция, как многим кажется :) Это ведь всего лишь специальный объект со своими методами и полями. И если одновременно запущенных потоков — минимум, то на что там может уйти так уж много процессорных тактов, я так и не понимаю.

Смотрите: у нас неизвестная конфигурация машины, например простенький компьютер в серверной стойке — 4 процессора по 4 ядра по 2 потока на каждое. А теперь нам надо удостовериться, что кеш по объекту одинаковый на всех этих потоках. Я не знаю точную реализацию монитора в java (да и зависит это от jvm), но возьмём простейший случай — по аналогии с volatile переменными: при каждом обращении к монитору мы должны загрузить (а после окончания операции — выгрузить) состояние из хипа. Т.е. процессор сбивается с текущей работы и начинает загрузку данных из RAM -> l3 кеш -> l2 кеш -> l1 кеш, после чего возвращается к выполнению инструкций дальше. В интернете достаточно много инфы по сравнению скорости доступа к каждому виду памяти — поищите, если интересно.
Т.е. в худшем случае (если массив не подгружен в текущий кеш) для вектора будет следующая процедура:


  • подгрузка данных монитора из RAM,
  • если монитор свободен — обновление данных монитора в RAM (если нет — вешаем поток и ждём сигнала и это совсем уже не быстрая процедура)
  • подгрузка или выгрузка данных массив из/в RAM (в зависимости от выполняемой операции… но это если кешей нет, а если нужный участок массива в кеше — в RAM не идём)
  • (вот в этой опреации не уверен, но по идее должна быть) загрузка данных монитора из RAM (чтобы освободить следующий поток, если есть такой)
  • сохранение данных монитора в RAM

Это приблизительная схема, как оно реально работает — это надо у разработчиков jvm уточнять.


Так я ж писал — нельзя серьёзный алгоритм (который может привести к серьёзным проблемам из-за багов) пихать в прод, толком не протестив.

Вы точно живёте не в мире розовых пони? Большинство заказчиков не готовы ждать даже просто 100%-ного покрытия тестами...


Особенно если программа многопоточная. Сначала юнит-тесты хотя бы сделать и прогнать надо…

юнит-тесты ничего не проверяют для многопоточной среды. Точнее не гарантируют качественную проверку. Банально во время теста jvm может работать на одном единственном ядре компьютера и фактически будет работать в однопоточном режиме.


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

А то ж! Тут главное, что стоимость одного куска проверенного вхлам кода не высока, а вот обеспечить подобное (в плане финансов*времени) для всей кодовой базы — большинство заказчиков не готовы.


А чтобы её решить, надо сам код переписывать. например, перед обходом коллекции делать копию, как я предложил выше.

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


За первое надо по рукам бить, второе — пытаться поймать на тестах. Ну или смириться с багами, которые вылезут потом :)

Когда искусственный интелект успел захватить мир? Я что-то не заметил, простите. Свойство биомассы таково, что "любой человек допускает ошибки". А ещё бывают криво прописанные требования. Тесты — тоже не панацея. Да и правильный стиль кодирования тоже, но в сумме это позволяет неплохо так повышать качество кода. Никто ж не говорит, что можно ляпать ошибки или не тестировать...


Только мест, где Вы будете его использовать, намного больше одного. И да, я вполне представляю проект, которые даже на сегодняшнем железе будет собираться в районе минуты (раз мой собирался 8 секунд при своём малом размере). Наверное, таких проектов даже немало.

Вы сейчас про сборку или про компиляцию? На сборку саму по себе синтаксический сахар вообще никак не влияет, только на компиляцию. Ваш проект, полюбому, компилировался пару-тройку секунд от силы.
Среднее время сборки не очень крупного проекта (не включая время тестирования) — 30-50 секунд на компьютере с hdd. А вот тесты у меня на текущем проекте ~8 минут суммарно гоняются… Так что те наносекунды, которые сожрёт синтаксический сахар меня совсем не интересуют. (даже если там будут тысячи вхождений — затраченное время всё равно окажется на уровне миллисекунд).


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

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


Вы говорите прямо как нас в вузе учили… Да вот только жаль у меня пока не выходит таких коротких функций в реальных проектах, даже там, где логика очень простая :) Примерно 25-30 строк получается.

Ну значит вам относительно повезло с преподами. А Роберт наш Мартин в своей книжке (чистый код — рекомендуется к прочтению) вообще ратует за функции не длиннее 5 строк, если я правильно помню. Но это на мой вкус — реально уж совсем мельчить. И да, изредка я не против существования функций 20-30 строк, но там должна быть какая-то уж совсем своя логика, которую трудно разбить на подшаги...


Давайте ещё раз. Я охотно верю, что стайлгайды могут многое запрещать, или наоборот, требовать. В том числе использование синтаксического сахара. Но. Обход массива без использования итератора — не такой страшный грех, как goto, всё-таки, на мой взгляд.

Нарушение принятых на проекте конвенций — как раз того же уровня грех (ибо goto запрещён теми же стайлгайдами). Ну и как изначально писали люди — после небольшого привыкания (это если первый раз видите foreach, а раньше пользовались for на индексных целочисленных итераторах) это банально легче читается. А чем легче читается — тем меньше ошибок. Правда-правда. Меньше шансов перепутать переменную индекса (ибо 0), меньше шансов перепутать переменную в которую читается элемент массива (ибо в объявлении цикла), меньше шансов промахнуться мимо нужной переменной в слачае обработки элемента массива.


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

По мне — и этих двух ситуаций хватает, чтобы предпочесть foreach


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

В большинстве случаев — плевать нам с высокой колокольни на иммутабельность. А вот в тех редких случаях, когда она внезапно уже потребуется (после какой-нибудь мелкой фичи в совсем другом месте) — так хоть легче будет продиагностировать проблему. И я вам уже приводил пример, когда пусть лучше прервётся, чем отработает с неправильными данными.


Ну и напоследок. Мне вот очень приятно и привычно видеть обход любой коллекции глазами в коде как for и буковки i (ну привычка такая за много лет сформировалась уже).

Поработайте с месяцок только с foreach и вам уже перестанет этот вариант казаться таким уж удобным. Правда. Большинство к этому приходят.


Использование итератора в чистом виде подразумевает или использование while (и одна доп. строка сверху для создания итератора), или использование for без третьего выражения

Ну что вы уж так-то?! Ведь синтаксический сахар foreach раскладывается примерно в следующую картину:


for (Iterator it = list.iterator(); it.hasNext(); SomeClass element = it.next()) {...}

Ну или на while можно аналогичным образом написать.


PS и я бы не сказал, что foreach используется всегда. Приведённый мной пример можно использовать, если есть потребность модифицировать массив (итератор позволяет, как минимум, удалять текущий элемент… возможно поддерживается и операция вставки до/после, но тут я ничего сказать не могу — слишком редко пользуются итератором… впрочем если коллекция такого не позволяет, то попытка изменения через итератор выбросит исключение :-)

0
Т.е. в худшем случае (если массив не подгружен в текущий кеш) для вектора будет следующая процедура

Если у нас не серверное приложение, и процессор один (допустим, многоядерный) — то очень может быть, что часть этих пунктов не понадобится, если монитор находится в кэше процессора одного из уровней. Или он в принципе не может там оказаться? Я плохо в этом понимаю, объясните плиз.

Также хотел бы отметить, что и само обращение к данным иногда идёт через RAM (если поле volatile). И я так понимаю, в случае с Vector JVM попытается обновлять данные массива именно в RAM при каждой записи, чтобы не было проблем у других потоков. Или же такое обновление будет только перед чтением (когда актуальные данные потребуются другому потоку)?

Большинство заказчиков не готовы ждать даже просто 100%-ного покрытия тестами...

Ну позвольте, где я писал про 100%? И вообще, заказчик часто в это вовсе не лезет, ибо не разбирается — и степень покрытия остаётся чисто на усмотрение разработчика. Как по мне, процентов 60-70 уже неплохо.

юнит-тесты ничего не проверяют для многопоточной среды. Точнее не гарантируют качественную проверку. Банально во время теста jvm может работать на одном единственном ядре компьютера и фактически будет работать в однопоточном режиме.

Ясно. А есть какие-то способы тестирования многопоточных программ (автоматизированные)?

это основная проблема, потому что чаще ломается не новый код, а зависимый от изменённого…

И в этот момент мне снова показалось, что хороший юнит-тест, проверяющий совокупную работу нескольких логических модулей в связке, мог бы такие проблемы быстро выявить… Но это я теоретизирую :)

Вы сейчас про сборку или про компиляцию? На сборку саму по себе синтаксический сахар вообще никак не влияет, только на компиляцию.

Про всё в сумме. Команда Build в контекстном меню проекта :)

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

Вот здесь вообще Вас не понял. Лень — это использовать дебаг, или лень когда его не используют? Ваш метод явно сложнее, дольше и контринтуитивнее. Смотрите, у нас идёт какая-то хитрая работа с индексами, и мы знаем, что у нас опечатка, возможно несколько раз. Чем хуже поставить брейкпоинт и посмотреть на реальные значения индексов по сравнению с исправлением «на глазок» и последующим перепрогоном теста? Тем более, если код свежий или вообще писался прямо только что, теста по нему может не быть от слова «совсем».

И да, изредка я не против существования функций 20-30 строк, но там должна быть какая-то уж совсем своя логика, которую трудно разбить на подшаги...

Кстати, когда я писал основу для браузерного движка, у меня получались кошмарно огромные функции. Главной проблемой разбиения на более мелкие методы было то, что в рамках метода у меня доступен целый набор локальных переменных, которые в случае разбиения на несколько вспомогательных методов нужно как-то в них передавать (а их много, и это приведёт к совершенно кошмарным сигнатурам). Делать эти значения полями класса — как-то совсем моветон. Как бы Вы отрефакторили такой длинный метод (речь идёт о Java)?

меньше шансов перепутать переменную в которую читается элемент массива (ибо в объявлении цикла)

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

В большинстве случаев — плевать нам с высокой колокольни на иммутабельность. А вот в тех редких случаях, когда она внезапно уже потребуется (после какой-нибудь мелкой фичи в совсем другом месте) — так хоть легче будет продиагностировать проблему. И я вам уже приводил пример, когда пусть лучше прервётся, чем отработает с неправильными данными.

Когда реально плевать — и обычный for не навредит, т.к. один поток. Когда не плевать — согласен насчёт того, что быстрее и легче продиагностировать.

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

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

Ну что вы уж так-то?! Ведь синтаксический сахар foreach раскладывается примерно в следующую картину

Это если использовать ещё одну переменную. А на самом деле можно ведь и напрямую в теле цикла использовать it.next(), а читать обычно нужно в переменную, определённую в методе выше до цикла (подсчёт суммы, копирование в другую коллекцию).

итератор позволяет, как минимум, удалять текущий элемент

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

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


Также хотел бы отметить, что и само обращение к данным иногда идёт через RAM (если поле volatile). И я так понимаю, в случае с Vector JVM попытается обновлять данные массива именно в RAM при каждой записи, чтобы не было проблем у других потоков. Или же такое обновление будет только перед чтением (когда актуальные данные потребуются другому потоку)?

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


Ну позвольте, где я писал про 100%? И вообще, заказчик часто в это вовсе не лезет, ибо не разбирается — и степень покрытия остаётся чисто на усмотрение разработчика. Как по мне, процентов 60-70 уже неплохо.

Ну вот и не будет у вас список покрыт тестами. А потом в нём ошибка. Какая лучше — с исключением или с испорченными боевыми данными?


Ясно. А есть какие-то способы тестирования многопоточных программ (автоматизированные)?

Что-то определённо есть, как минимум нагрузочное тестирование в том числе может показать проблемы параллельного доступа… но вот методов гарантирующих вызов некоторых мелких кусков кода в параллель я не припоминаю.


Вот здесь вообще Вас не понял. Лень — это использовать дебаг, или лень когда его не используют? Ваш метод явно сложнее, дольше и контринтуитивнее. Смотрите, у нас идёт какая-то хитрая работа с индексами, и мы знаем, что у нас опечатка, возможно несколько раз. Чем хуже поставить брейкпоинт и посмотреть на реальные значения индексов по сравнению с исправлением «на глазок» и последующим перепрогоном теста? Тем более, если код свежий или вообще писался прямо только что, теста по нему может не быть от слова «совсем».

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


Кстати, когда я писал основу для браузерного движка, у меня получались кошмарно огромные функции. Главной проблемой разбиения на более мелкие методы было то, что в рамках метода у меня доступен целый набор локальных переменных, которые в случае разбиения на несколько вспомогательных методов нужно как-то в них передавать (а их много, и это приведёт к совершенно кошмарным сигнатурам). Делать эти значения полями класса — как-то совсем моветон. Как бы Вы отрефакторили такой длинный метод (речь идёт о Java)?

Ну так я же не вижу реальный пример. Возможные пути:


  • вынести локальные переменные в какой-либо класс и уже их передавать параметром,
  • выделить относительно атомарные действия (даже если найдётся 4 атомарных действия в 2-3 строки длиной, то мы из 25 строк метода получим 17-21 строку, что уже много лучше
  • выбросить старый код и написать новый с новой архитектурой, в которой найти способ изначально ослабить взаимозависимость элементов.
    И да для web-движка это может быть малоэффективным, посколько там бывает много сопряжённых действий.

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

почитайте тут на хабре статейки про статический анализ (особенно выделяется рекламными постами одна компания-производитель дорогово пром. стат. анализатора, не помню сейчас её название — регулярно пишут… и проверка "похоже на опечатку" у них достаточно часто стреляет).


Когда реально плевать — и обычный for не навредит, т.к. один поток. Когда не плевать — согласен насчёт того, что быстрее и легче продиагностировать.

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


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

Ну да, пример надуманный — для наглядности. И работать он будет и на локальной машине. Только на совсем уж древним компьютерах с одним вычислительным потоком у них почти нет шансов.


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

А тут уже вопрос к "бизнесу" — какое решение должно быть. Более того, в нормальной ситуации описаный пример будет легко поправить заиспользовав транзакции БД и правильно спроектировав процедуру удаления работника. Но если всё держать "в памяти" — то там тот ещё простор решений, от вашего версионирования до CopyOnWriteArrayList-а и велосипедах на каких-нибудь ReentrantLock.

0
но вот методов гарантирующих вызов некоторых мелких кусков кода в параллель я не припоминаю

Это и не нужно. Можно просто гонять всё в цикле много-много раз, и рано или поздно такая ситуация всплывёт сама :)

Если есть бага — то код писался ну точно не вот прям счас

С чего Вы взяли? У меня такое сплошь и рядом — написал код только что, а он творит какую-то дичь во время запуска :) И я не против написания теста в дальнейшем, но дебаг в данном случае правда нагляднее и быстрее.

выделяется рекламными постами одна компания-производитель дорогово пром. стат. анализатора, не помню сейчас её название — регулярно пишут… и проверка «похоже на опечатку» у них достаточно часто стреляет

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

до CopyOnWriteArrayList-а

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

И да для web-движка это может быть малоэффективным, посколько там бывает много сопряжённых действий.

Может и так. А может, я просто недостаточно думал над этим вопросом. Могу скинуть Вам в личку код функции отрисовки тени для прямоугольного блока, если интересно. Там вообще какая-то жесть на 100 строк почти.
0
Это и не нужно. Можно просто гонять всё в цикле много-много раз, и рано или поздно такая ситуация всплывёт сама :)

Если бы! Некоторые вещи даже в проде до существенного повышения нагрузки не сразу всплывают… Тот же классический Java-вский DateTimeFormatter (или как он там называется… запамятовал) — ведь два года в проде провисел, прежде чем начал изредка хрень вносить в данные!


С чего Вы взяли? У меня такое сплошь и рядом — написал код только что, а он творит какую-то дичь во время запуска :) И я не против написания теста в дальнейшем, но дебаг в данном случае правда нагляднее и быстрее.

С того, что бага — это ужепосле перехода формального модульного тестирования к полноценному функциональному. Если речь не про пет/учебный проект, то обычно этим занимается другой человек, а ты уже потерял контекст. А если вы говорите про кривой алгоритм во время модульного тестирования — то это не бага, а ошибка алгоритма… Чисто формальные различия.


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

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


Может и так. А может, я просто недостаточно думал над этим вопросом. Могу скинуть Вам в личку код функции отрисовки тени для прямоугольного блока, если интересно. Там вообще какая-то жесть на 100 строк почти.

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

0
Тот же классический Java-вский DateTimeFormatter (или как он там называется…

Называется он SimpleDateFormat, и он действительно не безопасен — потому что на самом деле™ форматирует не java.util.Date, а вовсе даже java.util.Calendar — и оный является полем класса, и на него бывает гонка, о чём есть заметки во всех javadoc'ах по этому семейству классов.


А вот DateTimeFormatter добавлен в java 8, и он потокобезопасный, и это важно — а то так будут ходить слухи, что в "Java нельзя даже нормально время отформатировать в многопоточном приложении". Правда, им уже нельзя форматировать ни java.util.Date, ни java.util.Calendar, ну да туда им и дорога.

0
и на него бывает гонка
А можно попроще, для новичка — как эта гонка выглядит в псевдокоде и при чём тут то, что кто-то является чьим-то полем?
0
Выглядит вот так:
class SimpleDateFormat {
    private Calendar calendar = Calendar.getInstance();

    public String format(Date theDate) {
        calendar.setTime(theDate);

        return format(calendar);
    }
    
    private String format(Calendar calendar) {
        ...
    }
}

/**....*/

class Main {
  static SimpleDateFormat formatter =
                   SimlpeDateFormat`yyyy-MM-dd`;

  public static int main(String[] args) {
    ExecutorService exc =
            Executors.newFixedThreadPool(10);

    IntStream.range(0, 1000).forEach(val -> {
      exc.execute(() -> {
        Date theDate = Date.from(
            Instant.now().plus(val, DAYS)
        );
        System.out.println(String.format(
            "Days in future %d, date %s",
            val,
            formatter.format(theDate);
        ));
      });
    });
  }
  exc.shutdown();
  exc.awaitTermination(
      Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}


Мы собираемся печатать дату, которая отличается на val дней от сегодня. Но из-за вызова setTime внутри format(Date) на одном и том же объекте может получиться (а может и не получиться — именно поэтому баг такой гадкий) так, что напечатана будет какая-нибудь другая дата — например, если между вызовом setTime и format(Calendar) в одном треде произойдёт вызов setTime в другом треде, и это значение попадёт в кэш и будет загружено в первый тред. Тогда если сегодня — `2019-04-01`, мы можем увидеть в консоли что-то типа "Days in future 3, date 2019-04-26".
0
Спасибо, понятно.

То есть я правильно понял, что если у нас однопоточное приложение (это всё-таки наиболее частый случай), то проблем с этим классом нет?

И ещё — можно ли как-то решить эту проблему путём блокировок? Например, поставить где-то блоки synchronized? Я понимаю, что класс встроенный, и наследоваться от него — наверное идея не очень. Можно ли решить проблему, меняя только вызывающий код?

И с кэшем я не очень понял. Верно ли я понимаю, что экземпляр Calendar.getInstance() — один на все потоки? Тогда вообще всё тривиально конечно.

private Calendar calendar — это вроде бы ссылка на объект. Объект никуда не копируется и лежит в общей памяти. Один поток его изменил — объект изменился для всех потоков. Или объекты могут копироваться в кэш-память процессора как и скалярные переменные?
0
если у нас однопоточное приложение (это всё-таки наиболее частый случай), то проблем с этим классом нет?

Да. Если компилятор может доказать, что на доступ к полю не будет конкуренции, то он может и synchronized-блоки убрать. Ну, или облегчить.


Я понимаю, что класс встроенный, и наследоваться от него — наверное идея не очень

Нет проблемы наследоваться от любого не-final типа в JDK, если соблюдать LSP. Но если идея здесь — сделать собственный тип с мониторами на внутренний Calendar — думаю, гарантий не прибавится, т.к. нужно видеть полный набор операций, который конкретный поток делает с formatter'ом.


Конкретно эта именно проблема может — и должна, раз уж разработчики JDK не решают сами — быть решена на стороне вызывающего кода, например, синхронизацией на сам formatter — тогда будут гарантии, что каждый поток владеет состоянием formatter'а безраздельно, но при этом и программа становится, фактически, однопоточной:


synchronized(formatter) {
  System.out.println(String.format(
      "Days in future %d, date %s",
      val,
      formatter.format(theDate);
  ));
}

Верно ли я понимаю, что экземпляр Calendar.getInstance() — один на все потоки?

Да, верно. Но это не было бы проблемой если изначально разработчики не использовали бы этот экземпляр для хранения даты в процессе форматирования, а хотя бы клонировали его при начале форматирования/парсинга. К сожалению, имеем то, что имеем.


Или объекты могут копироваться в кэш-память процессора как и скалярные переменные?

Честно говоря, не уверен. Насколько я понимаю, так копироваться в кеш может ссылка на объект, и при этом не даётся никаких гарантий касаемо happens-before если ссылки/поля не выполняются в контексте какого-нибудь монитора, но я могу сильно ошибаться.


Зато вот нашёл статью про модель памяти, может, там есть ответ: https://habr.com/ru/company/golovachcourses/blog/221133/

0
думаю, гарантий не прибавится
Да, верно. Но это не было бы проблемой если изначально разработчики не использовали бы этот экземпляр для хранения даты в процессе форматирования, а хотя бы клонировали его при начале форматирования/парсинга. К сожалению, имеем то, что имеем.
Так вот этот метод при наследовании можно было бы и переопределить.

думаю, гарантий не прибавится, т.к. нужно видеть полный набор операций, который конкретный поток делает с formatter'ом
Зачем? Вы ведь привели проблемный участок кода самого класса SimpleDateFormat. Или речь про то, что могут быть и другие, и все их искать долго?

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

Нет проблемы наследоваться от любого не-final типа в JDK, если соблюдать LSP.
Что такое LSP?

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

Это был настоящий ад — в первую очередь потому, что значительная часть методов, которые использовались в переопределяемых методах, имели модификатор private. И при этом мне нужно было их вызывать. Я не нашёл способа лучше, как копипастить код существующей реализации…

А в другой раз (когда я пытался экспериментировать с «низкоуровневыми» методами вывода строк, и пытался наследовать jLabel), было ещё того хуже: внутри наследуемого класса повсеместно использовался вспомогательный класс, который имел «пакетный», а не публичный доступ. И по понятным причинам я его подключить к себе не мог.
0
Так вот этот метод при наследовании можно было бы и переопределить.

К сожалению, нет, нельзя — мякотка проблемы находится не там, где происходит setTime, а внутри метода format(Calendar). И состоит она в том, что нет никакого такого метода — есть метод, работающий с полем Calendar, загружая его значение из ссылки this.calendar. Даже если бы мы что-то переопределили и клонировали бы, нам пришлось клонированный экземпляр вписать в поле this.calendar — нас это не спасёт от гонки. Тут может помочь разве что сделать сам публичный внешний метод format synchronized — но решение неполное, т.к. остаются все прочие способы получить доступ к this.calendar, которые уже просто так синхронизировать не получится, бо мы не имеем над ними контроля. Решение поможет в моём псевдокоде, но создаст только иллюзию безопасности в общем случае.


Вы ведь привели проблемный участок кода самого класса SimpleDateFormat

Я привёл только самый простой пример. Есть ещё варианты, когда треды вызывают formatter::setTimeZone или formatter::setLenient перед вызовом formatter::format, и там тоже будут такие же по сути проблемы.


LSP

Liskov Substitution Principle


… Это был настоящий ад...

Этот опыт, что вы описываете, не о том, что сложно переопределить некий тип из JDK — он говорит о том, что сложно переиспользовать private-код из JDK. Здесь нет явной проблемы — в Java действительно не получится переопределить части, для которых не предусмотрена явно такая возможность, и это относится к вообще любому коду на Java.


Однако, ничто вам, в принципе, не помешает сделать


public class MyImmutableList<E>
  extends ArrayList<E> {
  @Override
  public void set(int index, E element) {
    if (!Objects.equals(element, get(index))) {
      throw new UnsupportedOperationException();
    }
  }
}

И как-то так получить список, в который можно добавить элемент, но нельзя заменить элемент, при этом сам список можно будет передавать почти в любой код, и вести он себя будет в соответствии с контрактами ArrayList(+ ваша надстройка) — можно итерироваться, добавлять/удалять элементы, брать размер списка, но попытка заменить элемент или отсортировать — приведут к ошибке.

0
есть метод, работающий с полем Calendar, загружая его значение из ссылки this.calendar
Это в каком именно методе происходит? Вот его логику можно было бы переопределить, чтобы он не с полем работал.

И как-то так получить список, в который можно добавить элемент, но нельзя заменить элемент, при этом сам список можно будет передавать почти в любой код, и вести он себя будет в соответствии с контрактами ArrayList(+ ваша надстройка) — можно итерироваться, добавлять/удалять элементы, брать размер списка, но попытка заменить элемент или отсортировать — приведут к ошибке.
Красивый пример. Но очень простой) Здесь ведь достаточно переопределения одного публичного метода.
0
Это в каком именно методе происходит?

Да вот в этом. Я вам точно говорю — снаружи синхронизировать будет куда проще.


Красивый пример. Но очень простой

Ну у меня не настолько хорошая фантазия или богатый опыт хаков JDK, чтобы я сходу могу придумывать сложные примеры. Впрочем и цели такой не было — показать что-то сложное. Основная идея как раз в том, что расширять типы из JDK — не сложно. По крайней мере, для доброй части типов.

0
Если речь не про пет/учебный проект, то обычно этим занимается другой человек, а ты уже потерял контекст. А если вы говорите про кривой алгоритм во время модульного тестирования — то это не бага, а ошибка алгоритма… Чисто формальные различия.
Да я в курсе про тестировщиков. Но всё равно не очень понимаю. Если в алгоритме нет формальной ошибки — откуда взяться багу? Плохая состыковка API двух разных модулей? Но такое тоже обычно на этапе компиляции всплывает всегда. Если только мы не гоняем что-то в сериализованном виде (например, по сети), и ошибка не закрадётся вот в эти самые данные перед их отправкой другому модулю (т.е. неверный формат исходящих данных).

лучше на гитхабе заведите открытый репо
Для TinyBrowser он есть. Могу дать ссылку
0

Вы почитайте про самые известные фейлы, некоторые из которых, например унесли реальные жизни, а потом говорите "откуда взяться багу". Как говорится — человеку свойственно ошибаться… а программы пишет человек. Тут и расхождение по бизнеслогике возможны и опечатки и неверно подобранный алгоритм и ещё вагон и маленькая тележка иных багов.


А можно попроще, для новичка — как эта гонка выглядит в псевдокоде и при чём тут то, что кто-то является чьим-то полем?

Опишу в виде примера, в SimpleDateFormat проблема похожая, но не так явно выглядящая. Есть класс A, у него есть поле, например int[] a. А внутри метод вида:


  this.a = a;
  StringBuilder sb = new StringBuilder();
  for (int i =0 ; i < this.a.length ; i++) {
    this.a[i] *= 2;
    sb.append(this.a[i]);
  }
  return sb.toString();
}

А теперь в параллельных потоках вызовем этот метод, в одном с массивом new int[] {2, 3, 4}, в другом с массивом new int[] {5, -2, 10}… и, допустим, случится так, что второй вызов произойдёт когда для первого пройдёт i=0 и перед i=1 (ну по какой-то причине нитка притормозила, например), получится что первый поток получит строку 4-420 (вместо ожидаемой 468), а второй поток получит строку 10-420 (как и ожидалось). Вот состояние, когда несколько потоков конкурируют за один и тот же ресурс и называется гонкой.


Там риски по безопасности сильно растут (особенно если это что-то антивирусное или связанное с передачей данных в облако). В своё время Dropbox вроде именно поэтому поддержку XP прекратил. А насчёт цены разработки — я бы всё же не согласился, не факт, что там всё становится прямо уж в разы сложнее. Что-то наоборот под старые ОС делать проще даже…

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


Ну не знаю. Я вот уже года 3 планирую прочитать книжку про программирование под Android. Как только научусь что-то более-менее писать — Android 2.3 точно буду поддерживать. Тем более у самого он стоит.

Ну вот вы из соображений "сам пользуюсь" "планируете" учитывать 2.3, но даже вы не планируете 2.1 (а то и 1.х), а будь у вас какой-нибудь 3.х/4.х/5.х — вы ба на той версии и остановились.


А почему? Если кому-то так нужны стримы и лямбды (хотя имхо это нужно редко) — ну есть 8-ая в конце концов. Но в основном и 7-ой хватает за глаза и за уши (ладно, с 6-кой я погорячился, она не умеет неблокирующий ввод-вывод толком, и менее гибко работает, например, с атрибутами файлов). В 7-ой версии с этим всё на порядок лучше и приятнее.

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


Так оно только в системном L&F — и естественно, работает только на винде. Не вижу причин, почему использовать Windows Forms или WPF можно (при этом разработчик приложения ничего не отчисляет Microsoft за возможность выводить их контролы на экране), а Swing — нет. Если JVM дёргает обычный Windows API в этом случае, то никакие лицензии не нарушены, вроде.

Фишка в том, что это работает на винде. В Linux/MacOs системный будет действительно системным, а не виндовым, соответственно ClearType-а там не будет, если его не поддержит сама система. L&F "а-ля виндовс" с собой технологию не потащит (и даже в винде не факт, что заработает).


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

0
и опечатки и неверно подобранный алгоритм
Так это всплывёт на юнит-тестах обязательно.

Вот состояние, когда несколько потоков конкурируют за один и тот же ресурс и называется гонкой.
Спасибо, понятно. Ну тут на мой взгляд в момент вызова в начале метода надо копию массива делать, а не работать с тем, что есть. Или как-то сделать так, чтобы для каждого потока был свой экземпляр поля (кстати, так вообще можно?).

Фишка в том, что это работает на винде. В Linux/MacOs системный будет действительно системным, а не виндовым, соответственно ClearType-а там не будет, если его не поддержит сама система. L&F «а-ля виндовс» с собой технологию не потащит (и даже в винде не факт, что заработает).
А где я предлагал тащить виндовый ClearType повсюду?)) Я понимаю, что главная фишка Java — кроссплатформенность. Но конкретно я хотел именно под Windows иметь браузер с чётким выводом текста. Да ещё и под конкретную её версию (хотя тестировал код и на более новых, и с разным DPI в настройках) :)

По остальному согласен полностью.

Да, если вдруг захотите улучшить тот проект (там ещё до финиша ох как далеко) — то буду очень рад пуллреквестам :)

github.com/popov654/tinybrowser
0
Так это всплывёт на юнит-тестах обязательно.

при 100% покрытии, спровоцированном TDD — да, проблема опечаток будет решена. На текущий момент TDD распространена достаточно плохо. Проблема неверного алгоритма — в лучшем случае частично решена будет. Однако в части случаев получится так, что на тестовом наборе всё ок, а в проде — ошибки.


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

это была упрощёнyая иллюстрация того, что происходит в SimpleDateFormat. Как с этим борются? Ну три основных способа: а) каждый раз создаём новый SimpleDateFormat (в целом не очень оптимальное решение, но этот класс имеет не сильно большие накладные расходы по памяти… хотя вот по времени исполнения получается уже хуже), б) синхронизация вызовов объекта (и на этом участке получается однопоточное приложение) и в) упаковываем в ThreadLocal — этот объект позволяет создавать инстанс объекта для каждого потока индивидуально (тоже не без минусов — во-первых всё-таки объектов будет больше одного, во-вторых при неправильном обращении с ThreadLocal можно получить неплохую такую утечку памяти). Ну а в приведённом мной примере — да, действительно нужно было просто копию массива делать… или ещё лучше решение — просто не сохранять в переменные инстанса, а передавать по всей цепочки вызовов параметром… но иногда это сложно сделать архитектурно — если требуется много действий… но в такой ситуации надо всю архитектуру переделывать на самом деле.

0

Теперь есть ещё четвёртое решение — пользоваться чем-то более приятно написанным, чем старые DateTime-части JDK. Например, потокобезопасным форматтером:


  static DateTimeFormatter formatter = ...?profit

  public static String formatMyTime(Date date) {
    ZonedDateTime zdt = date.toInstant()
        .atZone(formatter.getZone());
    return formatter.format(zdt);
  }

В отсутствие Java8 можно "перебиваться" Joda. Если хочется совсем упороться — то взять Time4J.

0

До принятия йоды в JDK это было мало для кого вариант — всё же одно дело нативные сущности, другое — привнесённые. Удобство использования просто разное. Да и в йоде по удобству АПИ есть сложные моменты. Радует только то, что вопрос именно к удобству. Т.е. если говорить java 7 (и более ранних) — для них существуют по большей части предложенные мной решения. Да и в целом ваше решение — оно уже не решение проблемы потокобезопасного использования заданного класса — оно решение использовать что-то вместо него.

0

У меня, честно говоря, никогда не стоит прямо задачи "используй экземпляр этого класса потокобезопасно" (разве что в каком-нибудь тесте) — как правило, требование более высокое — "у нас неправильно форматируется время в час пик, почини".


Кстати, для именно более высоко сформулированной задачи в Java7 Joda тоже будет решением, потому что умеет вот так: DateTimeFormatter::print(long millisecond-instant)
— а значит без проблем работает где-нибудь в виде метода-утилиты, и не будет заставлять вас отказываться от использования Calendar'ов в API.


в йоде по удобству АПИ есть сложные моменты

Расскажите про это подробнее.

0

Ну как простейший пример — попробуйте без дополнительных телодвижений распарсить 2012-11-30 в LocalDateTime или OffsetDateTime. Вылетит исключение, что он не может создать нужные типы, потому что нет таких-то полей (вроде наличие часа в строке хватило бы, не помню уже). Это можно обойти донастроив парсер, чтобы он вставлял 0 если часы-минуты-секунды отсутствуют.

0
нельзя распарсить 2012-11-30 в LocalDateTime

Логично — ведь в строке не указано время, и не бывает "времени по умолчанию". У вас там дата — значит, работать надо с датой, LocalDate. Это, к слову, намного удобнее чем работать с "моментом, указывающим на начало дня, в базе он хранится как UTC, а клиенту надо будет показать тоже начало дня, но в его часовом поясе, смотри не перепутай".


То же самое с OffsetDateTime — какой часовой пояс вы предлагаете считать "поясом по умолчанию"? Если пояс сервера — юзайте LocalDateTime сразу. Статически задать пояс нельзя пока "Europe/Moscow" означает два или более разных сдвига в зависимости от хотелок политиков.


Я наоборот назову это более хорошим дизайном API — вы сразу знаете, что вы дали на вход и что вы получите в качестве результата. Не как раньше, где в принципе не было понятия каледнарной даты, нельзя было никак выразить требование "каждые два дня в 19:16", а Calendar.getInstance() мог вернуть вам буддийский календарь, и ничего вы с этим просто так не поделаете — сколько кода вы видели, который пишет new GregorianCalendar()?


А ваша проблема действительно решается "донастройкой парсера", и это делается один раз, в утилите:
Либо


var staticFormatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_DATE)
    .appendOptional(DateTimeFormatter.ISO_TIME)
    .parseDefaulting(ChronoField.NANO_OF_DAY, 0)
    .toFormater();

staticFormatter.parse("2012-11-30", LocalDateTime::from);

new DateTimeFormatterBuilder()
    .append(staticFormatter)
    .parseDefaulting(ChronoField.OFFSET_SECONDS,
//помните, что offset_seconds зависит от "сейчас"?
        ZoneId.systemDefault()
        .getRules()
        .getOffset(Instant.now())
        .get(ChronoField.OFFSET_SECONDS)
    ).parse("2012-11-30", OffsetDateTime::from);

Либо, раз уж так охота не знать, пользуетесь вы форматом для даты, момента или локального момента:



DateTimeFormatter.ofPattern(externalPattern)
    .parseBest(dateString,
        OffsetDateTime::from,
        parsed -> LocalDateTime.from(parsed)
            .atZone(ZoneId.systemDefault())
            .toOffsetDateTime(),
        parsed -> LocalDate.from(parsed)
            .atStartOfDay(ZoneId.systemDefault())
            .toOffsetDateTime()
    );
0
Статически задать пояс нельзя пока «Europe/Moscow» означает два или более разных сдвига в зависимости от хотелок политиков.
При чём тут хотелки политиков? В конкретный момент времени сдвиг для Москвы всегда однозначен, и для временных зон всё это хранится (вся история изменений). То есть для каждой временной метки в UTC можно однозначно посчитать её локальное представление. В чём здесь проблема-то?

То, что я вижу в коде выше, выглядит громоздко и страшно, как по мне…
+1
То есть для каждой временной метки в UTC можно однозначно посчитать её локальное представление

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


выглядит громоздко и страшно, как по мне…

Код выглядит громоздко от того, что изначально постановка задачи предполагает, что кто-то должен сделать много допущений. Как вы (должно быть) знаете, OffsetDateTime — это как раз момент времени, специфическая его форма, когда часовой пояс представлен неким смещением относительно UTC. При этом, в строке "2012-11-30" содержится только дата. То есть, чтобы составить из этой даты момент времени, нам не хватает "всего-то" остатка совы — времени и смещения относительно UTC. Вы кому предлагаете эти данные "родить" — разработчикам стандартной библиотеки, которые о специфике вашей программы ничего не знают? Нет, согласно дизайну java.time допущений следует делать как можно меньше (в идеале — не делать вообще), и все необходимые данные нужно предоставить разработчику, так как это он лучше должен знать, какие допущения можно делать, а каких — нельзя. Вот второй блок кода как раз этим и занимается, кстати — говорит, что делать парсеру если данных недостаточно, а OffsetDateTime всё-таки нужен. Причём, вот это всё вообще можно вынести в соответствующую утилиту, назвать метод getOffsetDateTimeFromAnyString, и там в комментариях объяснить всю степень редисочности вашей внешней системы, которая меняет формат кодировки дат непредсказуемым образом.


С другой стороны, если вам всегда приходит yyyy-MM-dd, и вам, опять же, всегда нужен оттуда OffsetDateTime на момент начала дня в Мадриде, нет ничего проще:


private static
DateTimeFormatter frmt = DateTimeFormatter
    .ofPattern("yyyy-MM-dd");

public static
OffsetDateTime parse(String input) {
    return LocalDate.parse(input, frmt)
        .atStartOfDay(ZoneId.of("Europe/Madrid"));
        .toOffsetDateTime();
0
Спасибо, возьму на заметку. Похоже, подход и правда верный (хотя мне кажется, было бы неплохо, если бы указание всех этих зон и смещений от полуночи было опциональным, а по дефолту бралась бы полночь по Гринвичу). Или там так и реализовано, и эту цепочку вызовов можно не чейнить, если и правда нужен Лондон на начало суток?
0

Нет, именно всякоразличных умолчаний там практически нет. Пожалуй, кроме возможности получить
XxxDateTime.now(),
которое, по сути, XxxDateTime.now(Clock.system(ZoneId.systemDefault())
(время по системным часам в часовом поясе машины).


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


Если вы из просто даты всегда хотите получать момент в UTC (не Лондоне!) на начало суток, то самое простое что я могу придумать — это сделать один раз соответстующий парсер со значениями по умолчанию. Как-то так


new DateTimeFormatterBuilder()
  // или append(DateTimeFormatter.ISO_LOCAL_DATE)
  .appendPattern("yyyy-MM-dd")
  .parseDefaulting(ChronoField.NANO_OF_DAY, 0)
  .withZone(ZoneOffset.UTC)
  .build();

Это достаточно делать один раз и сохранить в статическое поле — новые парсеры, в отличие от старого SimpleDateFormat потокобезопасные. Но вот "умолчаний" в парсерах нет. Они даже часовой пояс машины не используют — потому что если парсер дёргать из нескольких потоков и вдруг кому-то придёт в голову светлая идея поменять TimeZone.default… я думаю, вы понимаете.

0
> при 100% покрытии, спровоцированном TDD — да, проблема опечаток будет решена.

Не решена, а уменьшится количество инцидентов. Банально одна и та же опечатка может быть допущена и в тесте, в и коде. Причём просто возвести в квадрат вероятность опечатки нельзя — нередко это связанные события, события причина которых в особенностях конкретного человека, клавиатуры или IDE.
0
А давайте вы подучите матчасть для начала, потому что вы высказываете совершеннейшую дичь, не достойную даже Junior Java Developer. Почитаете, почему закопали Vector, какой оверхед вносит synchronized, про менее грубые методы синхронизации, чем synchronized, и так далее.
0
почему закопали Vector

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

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

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

Когда я говорил «закопали», я имел в виду нормальных людей, а не некрофилов.
А ссылкой на более правильные и мягкие методы синхронизации не поделитесь? Я бы почитал.

docs.oracle.com/javase/tutorial/essential/concurrency.
+1
Никто его не закопал, многие и сегодня прекрасно его используют.

Никто его не использует.


Особенно, если синхронизация действительно нужна.

Особенно важно не использовать Vector, если нужна синхронизания.

0
А обход итератором не станет квадратичным ни с array, ни с linked list.
0
Создать один итератор (константная, притом мизерная, память и практически константное и опять же мизерное время)

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


или превратить линейное время итерации в квадратичное,

А каким образом время итерации превратится в квадратичное? Если мы передадим туда не ArrayList, а что-то другое? Не то чтобы это совсем невероятно, но само наличие коллекции типа LinkedList, передаваемой туда, где ждут List — это уже очень подозрительно и обычно отсекается на уровне пул реквеста.

0
Если коллекция маленькая, то расходы на создание итератора сравнимы с расходами на итерацию по коллекции, или даже превышают их.

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

LinkedList редко, но используется. А еще не все коллекции бывают списками. Так что совершенно непонятно, зачем даже обсуждать использование заведомо худшего способа итерации.
0
Повторюсь, что это [создание итератора для foreach] небольшие константные расходы

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


LinkedList редко, но используется.

Я не помню, когда видел последний раз и не заменил на ArrayList.


А еще не все коллекции бывают списками.

Ну как я понял мы тут говорим только об интерфейсе List.


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

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


Кстати, если подходить к вопросу педантично, то в случае с итераторами есть ещё вызов метода next у итератора, который пусть немного, но медленнее, чем инкремент i. ))

0
Как говорил Кнут, преждевременная оптимизация хуже преждевременной эякуляции. Это как раз про то, чтобы изговнякать код ради мифической экономии наносекунд и байтов (на Java!) просто потому, что ты мамкин оптимизатор.
0
Как говорил Кнут, преждевременная оптимизация хуже преждевременной эякуляции.

Вы цитируйте, не стесняйтесь )). А лучше, я процитирую.


In established engineering disciplines a 12% improvement, easily obtained, is never considered marginal; and I believe the same viewpoint should prevail in software engineering.

На русский переводится примерно так:


В сложивщейся инженерной дисциплине улучшение на 12% легко получаемое никогда не считают незначительным; и я верю, что та же самая точка зрения должна господствовать в разработке программного обеспечения.

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


Обычно код запускают, профилируют, находят узкие места и, если одним из таких узких мест оказывается итерация по коллекции — с помощью IDE заменяют там foreach на стандартный for. А потом проверяют помогло, или нет.

0
Так кто ж спорит-то, что если при профилировании доказали, что foreach — узкое место, то можно и заменить его на for. Выше, как я понял, товарищ сетовал на неэффективность foreach в вакууме и предлагал поэтому использовать for по умолчанию. Вот это я и называю преждевременной оптимизацией, т.к. код испортили, не доказав необходимость этого.
0
Тут может быть противоположное мнение: пока не показано, что цикл for узкое место будем использовать его по умолчанию. Просто соглашение команды об умолчаниях.
0
Нет смысла в таком соглашении. Foreach по умолчанию универсальнее и лучше читается. For — узкое место с точки зрения всего этого с самого начала.
0
Что лучше читается — дело привычки. Есть люди, для которых foreach читается хуже, потому что оставляет слишком много вопросов без детального изучения документации. Например порядок обхода
0
Если у нас на входе абстрактная коллекция и мы ходим по ней форичем, ясно, что на порядок нам положить.
0
Смотрите, foreach подразумевает то, что о типе итерируемой сущности позаботится рантайм (или компилятор). В случае с JavaScript (я в основном пишу на нём), использование for… in, перебирающего все ключи объекта либо индексы массива — реально очень плохая идея, если у нас обычный массив. for всегда будет быстрее. JS правда, в отличие от Java, не компилируется в байт-код в общем случае (точнее, компилируется в него прямо перед исполнением, и время этой компиляции нам тоже важно).
0
Еще раз:
Вот это я и называю преждевременной оптимизацией, т.к. код испортили, не доказав необходимость этого.
0
Чем именно код портится от использования обычного цикла for? Ещё раз, опишу, как это работает в JS: при обходе через for key in obj (аналог forEach в Java) мы в переменную key получаем ключ. В случае объекта мы получим все поля (включая поля из цепочки прототипов, что может быть для нас лишним, поэтому в теле цикла нужно проверять, что у нас за поле), а в случае массива — там будут целочисленные индексы. И хотя в JS массив — это тоже объект, просто особого класса, всё же использование for… in влечёт некоторые дополнительные проверки. Как бы то ни было, на реальных бенчмарках, которые делали энтузиасты в разных браузерах в 2010-2011 году, производительность при использовании for… in проседала более чем вдвое. Собственно, тот же случай, что с использованием Vector, от использования которого вы меня здесь дружно отговариваете.

Да, Java — совсем другой язык, и там совсем другая картина. И best practices другие. Но просто у меня есть некоторые привычки (писать циклы именно так), и я пишу так абсолютно в любом языке, потому что единообразие — это удобно с точки зрения скорости кодинга и быстроты «переключения» на другой язык.
0

Как бек, с навыками фронта (не дотягиваюя до звания фуллстека) могу вам с уверенностью сказать: в каждом языке лучше применять best practices конкретно этого языка.
И for… in в js это совсем не то же самое, что foreach в java.


А я не знаю, почему его не сделали. Множествами я тоже не пользуюсь. Как по мне, это очень неудобная коллекция — например хотя бы потому, что для её обхода необходим итератор (то есть нельзя проитерироваться по ней в цикле for, что, я настаиваю, является самым интуитивным подходом). И не сделав метод get (хотя да, он не имеет смысла, потому что у элементов нет уникальных ключей, а если они будут, то это будет уже хэш-таблица), разработчики JDK серьёзно подпортили универсальность интерфейса, т.е. независимость реализации от типа используемой фактической коллекции.

Всё разработчики JDK очень грамотно посчитали — Set вполне имеет своё уникальное предназначение и лишние методы (а-ля get) ему не нужны. Ну а вы из-за своих привычек просто отказываетесь от полноценного использования языка.

0
Извините за глупый вопрос, и где же лучше всего использовать Set? Назовите реальный, не придуманный пример, плиз. Или хотя бы приближённый к реальности. Всё, что мне приходит на ум — решается проще и нагляднее с помощью Hashtable/Hashmap.
0
Hashtable/Hashmap

Да сколько можно! Во-первых не используйте слово Hashtable в приличном обществе, во-вторых названия классов — HashTable и HashMap. Меня от каждого такого вашего комментария как демона от святой воды трясёт ))


Извините за глупый вопрос, и где же лучше всего использовать Set? Назовите реальный, не придуманный пример, плиз

Везде, где вы не хотите писать дополнительные комментарии, что Map используется не как Map, а как Set. То есть любой случай, когда вам надо проверить есть ли объект у чего-то, а больше ничего не надо. Классический пример — принадлежность пользователя к какой-нибудь группе.

0
во-вторых названия классов — HashTable и HashMap
Извините, случайная опечатка. И кстати, про Hashtable вы совершенно не правы. Именно так, как я написал. Вот фрагмент кода из моего серверного модуля к GraphBuilder:

private Socket sock;
private static boolean guiEnabled = false;
private static int max_index = 0;
private static int last = -1;
private static String sessionName = "";
private static String sessionKey = "0";
private static Date writeTime = new Date();
private static String[] newGraph;
private static Vector<String[]> dataStorage =
     new Vector<String[]>();
private static Hashtable<String, Integer> names =
     new Hashtable<String, Integer>();

Везде, где вы не хотите писать дополнительные комментарии, что Map используется не как Map, а как Set. То есть любой случай, когда вам надо проверить есть ли объект у чего-то, а больше ничего не надо. Классический пример — принадлежность пользователя к какой-нибудь группе.
Не убедили. Смотрите, у нас есть некое хранилище, где объекты — это пользователи (вы только что предложили, да и я вчера об этом думал). Если мы выберем Set — то мы не сможем быстро получить конкретного пользователя по ключу. А если там подробные данные о нём, или например хранится его последний чат (если мы анонимный чат пишем)? Или если там в одном из полей хранится ID этого самого чата? Или список ID чатов? В итоге нам придётся обходить всё множество, и сложность будет линейной. Имхо, хэш-таблица решила бы проблему лучше.
0
Не убедили. Смотрите, у нас есть некое хранилище, где объекты — это пользователи (вы только что предложили, да и я вчера об этом думал).

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

0
А, тогда хороший пример. Хотя можно было бы просто сделать класс-наследник для Vector ArrayList с кастомным методом add, проверяющим значение на уникальность :)

Но наверное, использовать стандартные коллекции — правильнее.
0
Хотя можно было бы просто сделать класс-наследник для Vector ArrayList с кастомным методом add, проверяющим значение на уникальность :)

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

0

Я вам по большому секрету скажу — HashSet под капотом — HashMap, ага.


Почему HashSet, а не HashMap? А зачем мне лишние сущности? Это будет отвлекать от основной цели объекта, да и оптимизировать хранение "значения" будет не совсем просто — всё-таки не даром HashSet это специальная реализация HashMap под капотом.


Почему не HashTable — потому же, почему не Vector. Мне не нужен устаревший синхронизированный класс.


Зачем использовать? Кеш объектов, словарь объектов, список объектов — которые нужны или целиком, или в которых нужен поиск по объекту… И нужно гарантировать, что элемент в списке будет ровно один (а в некоторых случаях дубли просто противопоказаны).


Не вижу никакой проблемы в поддержке кода с циклом for на индексах вместо цикла forEach. Вы какую-то проблему из пальца высасываете, честное слово…

Ну вот зачем вы свою психотравму из js тащите в java?! Объясню просто: нет никакого foreach в Java, есть синтаксический сахар for для обхода коллекции. На этом предлагаю спор о целесообразности тащить ужасные привычки из одного языка в другой закрыть.


PS Кстати, а стримов вы наверное совсем боитесь?

0
да и оптимизировать хранение «значения» будет не совсем просто
Не очень понял, что вы имеете в виду под оптимизацией. Быстрая проверка наличия объекта именно по объекту, а не по ключу? Окей, допустим. Возможно, если он оптимизирован лучше, чем HashMap, то и правда лучше использовать его. Про Hashtable понятно. Опять же, я использовал в одном проекте именно Hashtable, но не просто так: там хэш-таблица была в серверном модуле, и в неё действительно могли читать (а также одновременно в неё писать) несколько потоков. Я понимаю, что это не панацея, и у меня всё равно могло всё поломаться, потому что надо полноценные блокировки было вводить. Но имхо если бы я использовал HashMap, поломалось бы ещё быстрее и ещё хуже…

которые нужны или целиком, или в которых нужен поиск по объекту…
Поиск полным обходом что ли, с линейным временем? Вы сказали, что в HashSet оптимизирован поиск по значению, а не по ключу — но я не очень понимаю, как это поможет искать нам объекты по значениям отдельных полей, не строя какие-то дополнительные индексы своими силами…

Объясню просто: нет никакого foreach в Java, есть синтаксический сахар for для обхода коллекции.
Так его выше комментаторы окрестили как forEach, я-то при чём? В JavaScript, кстати, у массивов есть такой метод, принимающий как аргумент функцию.

На этом предлагаю спор о целесообразности тащить ужасные привычки из одного языка в другой закрыть.
Окей, но для меня всё же проще придерживаться одинакового стиля на всех языках, а не перестраиваться каждый раз. Мне даже переход с JavaScript на PHP 5.3-5.4 доставляет боль (потому что объявление ассоциативных массивов через => вместо :, произвольный объект надо объявлять как ассоциативный массив, если хочешь сделать это быстро и аккуратно, объединение строк через . вместо +, и доллары перед каждой переменной, что тратит время при наборе кода).

Кстати, а стримов вы наверное совсем боитесь?
Я знаю, что есть потоки в C++. Стримы появились только в Java 8, я пока ещё о них не читал, к сожалению. Но почитаю, спасибо. Если это что-то удобное — зачем их бояться, наоборот, надо использовать. Другое дело, я ради совместимости с более старыми ОС вряд ли вообще на 8-ой версии буду что-то разрабатывать. Я слышал, там некоторые вещи могут работать не очень.
0
Не очень понял, что вы имеете в виду под оптимизацией. Быстрая проверка наличия объекта именно по объекту, а не по ключу?

Оптимизация по памяти.


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

Для этого существует ConcurrentHashMap. Там есть всякие computeIfAbsent и прочие неблокирующе-синхронизирующие методы.


Поиск полным обходом что ли, с линейным временем? Вы сказали, что в HashSet оптимизирован поиск по значению, а не по ключу — но я не очень понимаю, как это поможет искать нам объекты по значениям отдельных полей, не строя какие-то дополнительные индексы своими силами…

Изучайте матчасть. В HashSet/HashMap сперва идёт поиск bucket, хранящий элемент по значению hashCode, после чего уже, да, идёт линейное сравнение для элементов, имеющих одинаковый hashCode. Поэтому для нормального функционирования этих коллекций необходимо чтобы ключ (для мапы) или значение (для сета) был корректно реализован метод hashCode.


Так его выше комментаторы окрестили как forEach, я-то при чём? В JavaScript, кстати, у массивов есть такой метод, принимающий как аргумент функцию.

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


Окей, но для меня всё же проще придерживаться одинакового стиля на всех языках, а не перестраиваться каждый раз. Мне даже переход с JavaScript на PHP 5.3-5.4 доставляет боль (потому что объявление ассоциативных массивов через => вместо :, произвольный объект надо объявлять как ассоциативный массив, если хочешь сделать это быстро и аккуратно, объединение строк через. вместо +, и доллары перед каждой переменной, что тратит время при наборе кода).

Я (правда исключительно теоретически) могу писать на java, c, c++, assembler, delphi, js и php. И в каждом языке придётся писать в соответствии с особенностями этого языка. Вы же не пишете xml в стиле json? так а чем полноценные-то языки хуже? Сосредоточтесь на 2-3 языках… если так хочется — обновляйте список каждые пару лет. Тогда и глупого желания писать как в других языках будет меньше. Ну и полезно годик-два повариться в ентерпрайзе, даже если потом к нему прикасаться не будете.


Я знаю, что есть потоки в C++. Стримы появились только в Java 8, я пока ещё о них не читал, к сожалению. Но почитаю, спасибо. Если это что-то удобное — зачем их бояться, наоборот, надо использовать. Другое дело, я ради совместимости с более старыми ОС вряд ли вообще на 8-ой версии буду что-то разрабатывать. Я слышал, там некоторые вещи могут работать не очень.

простите но вот это — первостатейный бред. Везде где jvm заданной версии запускается (а это более-менее все ОС, кроме совсем уж устаревших) все фишки заданной версии будут работать корректно.

0
Изучайте матчасть. В HashSet/HashMap сперва идёт поиск bucket, хранящий элемент по значению hashCode, после чего уже, да, идёт линейное сравнение для элементов, имеющих одинаковый hashCode. Поэтому для нормального функционирования этих коллекций необходимо чтобы ключ (для мапы) или значение (для сета) был корректно реализован метод hashCode.
Я знаю, что это за метод и что он делает. Вы вообще похоже меня не поняли, по ходу дела. У нас HashSet раскидывает элементы по бакетам в соответствии с хэш-функцией. Это так. Но как это нам поможет найти объект по значению какого-то отдельного поля в нём? Вот и получается, что поиск по сету объектов в общем случае, если у нас нет полной копии (которая вернёт тот же хэш-код) — будет линеен. А если у нас есть полная копия, то и искать как бы ничего не надо…

Поэтому я и предлагаю отказаться от путающего вас названия и пользоваться наименованием инструкции.
Хорошо.

Вы же не пишете xml в стиле json?
А это вообще как? Мой мозг отказывается такое представить.

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

Везде где jvm заданной версии запускается (а это более-менее все ОС, кроме совсем уж устаревших) все фишки заданной версии будут работать корректно.
Я неверно выразился, простите. Вот смотрите, при установке JRE 8 на WinXP установщик настоятельно рекомендует обновить версию ОС. А ещё там прогресс-бар выглядит при установке… Ну, странновато по дизайну. Это достаточный аргумент, чтобы остерегаться использовать на XP даже версию 8? Вот напишу я красивую форму на Swing — а у меня вот так же что-нибудь сломается. Нет, возможно там ничего не ломается, и это всё моя больная фантазия. Но если они даже инсталлятор сделали вот так вот тяп-ляп…
0
Я знаю, что это за метод и что он делает. Вы вообще похоже меня не поняли, по ходу дела. У нас HashSet раскидывает элементы по бакетам в соответствии с хэш-функцией. Это так. Но как это нам поможет найти объект по значению какого-то отдельного поля в нём? Вот и получается, что поиск по сету объектов в общем случае, если у нас нет полной копии (которая вернёт тот же хэш-код) — будет линеен. А если у нас есть полная копия, то и искать как бы ничего не надо…

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


А это вообще как? Мой мозг отказывается такое представить.

Это примерно так же, как на java писать в стиле js. Те кто пишут на java в регулярном режиме в лучшем случае будут плеваться про себя.


Согласен, но при чём тут нелюбовь к «переключению» на другой язык и работа в крупной компании? Вы к тому, что там неизбежно придётся писать на нескольких языках параллельно?

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


Я неверно выразился, простите. Вот смотрите, при установке JRE 8 на WinXP установщик настоятельно рекомендует обновить версию ОС. А ещё там прогресс-бар выглядит при установке… Ну, странновато по дизайну. Это достаточный аргумент, чтобы остерегаться использовать на XP даже версию 8? Вот напишу я красивую форму на Swing — а у меня вот так же что-нибудь сломается. Нет, возможно там ничего не ломается, и это всё моя больная фантазия. Но если они даже инсталлятор сделали вот так вот тяп-ляп…

И снова — учите матчасть. В пределах одной версии swing на всех компьютерах будет отображаться строго одинаково — это UI, который целиком и полностью строится на java. Вот если вы будете работать с AWT или SWT (или как там она называется) — тогда да, в каждой ОС всё будет выглядеть по-разному, т.к. UI будет строиться с использованием системных элементов.


PS ну и вообще вспоминать сейчас win XP в разработке не каких-нибудь станков, а обычных "формочных" приложений — моветон. Слишком маленький за ними рынок остался, чтобы на них реально затачиваться.


Можно ссылку на цитату разработчиков, где они такое говорят? И аргументацию, почему эти коллекции не были удалены из JDK?

Не удаляются — исходя из старого java-вского "обратная совместимость гарантируется". Из-за этого же не меняются контракты методов. Рекомендации не использовать эти коллекции — в javadoc этих классов, например в openjdk это звучит так, абзац со строки 65, а в javadoc к sun-овской/оркаловской jdk, насколько помню было прописано более негативный прогноз использования.

0
Это примерно так же, как на java писать в стиле js.
Ну вы всё же слишком разные вещи сравниваете. Java и JS — оба построены на ECMA Script, тогда как у JSON и XML вообще практически ничего общего (кроме общих понятий вроде «сущность» и «свойство»).

В пределах одной версии swing на всех компьютерах будет отображаться строго одинаково
А вы точно в этом уверены? Я читал, что элементы Swing — «легковесные». Но тем не менее, они выглядят абсолютно нативно, и ведут себя тоже нативно. Даже ClearType сглаживание работает совершенно одинаково на jLabel из Swing и на обычных Label из AWT (чего нельзя сказать о выводе строки или символа через API c помощью методов вывода, где сглаживание как раз не работает как надо, используя некий кастомный grayscale алгоритм, явно не имеющий отношения к ОС). Отсюда у меня есть сильные подозрения, что «под капотом» там вызывается совершенно стандартное API Windows, которое и рисует эти самые компоненты UI, а JRE только передаёт ему на вход нужные параметры отрисовки.

ну и вообще вспоминать сейчас win XP в разработке не каких-нибудь станков, а обычных «формочных» приложений — моветон. Слишком маленький за ними рынок остался, чтобы на них реально затачиваться.
Напрасно вы так. Не важно, какой там рынок, я вот ещё полгода назад видя ситуацию с окончанием поддержки Firefox пытался написать простой веб-браузер, который обрабатывал бы HTML, CSS и исполнял JS код, и при этом нормально работал бы на Win XP (и выводил там корректно сглаженный текст, с чем у того же Chrome большие проблемы были даже в версиях 22-49, а сейчас и вовсе который не поддерживается).

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

а в javadoc к sun-овской/оркаловской jdk, насколько помню было прописано более негативный прогноз использования
Вот здесь не понял. Что значит «более негативный прогноз»? И вообще, зачем начинать с openJDK, когда стандарт де-факто в отрасли, которым 90% людей пользуется — это JDK и JRE от Sun/Oracle? Она же бесплатная, верно? В чём там загвоздка, разве не логичнее использовать авторскую разработку, а не форк с неё, который к тому же непонятно, насколько совместим?

P.S. Прочитал вашу ссылку.

Unlike the new collection implementations, Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector
Тут не сказано «вы никогда не должны использовать, любое использование крайне не приветствуется». Тут сказано «если потоко-безопасная реализация не нужна, рекомендуется использовать альтернативы». Это сильно иначе звучит, не находите? :) Хотя да, я понимаю, что случай, когда она не нужна — самый частый, а рекомендации лучше соблюдать.

UPD: Я кажется понял, почему мы не поняли друг друга насчёт Swing. То, что писал я — применимо к моему опыту работы с System Look&Feel (который имитирует системный UI, а по факту, как оказалось, просто делегирует значительную часть операций отрисовки ОС). Для кастомных Look&Feel, включая тот, что установлен по умолчанию, вы несомненно правы — на любых ОС отображение будет одинаковым.

Но касаемо ClearType сглаживания у меня кстати есть большие вопросы, работает ли оно вообще в кастомных L&F. Судя по тому, что я вижу на XP при включенном ClearType (и корректно настроенном под монитор) — скорее нет, чем да: очень похоже на хороший grayscale, причём опять же реализованный внутри самой JVM. В принципе оно и логично: ClearType является частью шрифтового рендерера Windows, а Swing как раз призван обеспечить отображение независимое от ОС, чтобы было «всё везде одинаково». Потому и шрифт рисуется напрямую рантаймом.
0
Ну вы всё же слишком разные вещи сравниваете. Java и JS — оба построены на ECMA Script, тогда как у JSON и XML вообще практически ничего общего (кроме общих понятий вроде «сущность» и «свойство»).

Простите, что? Смотрим вики (русскую)[https://ru.wikipedia.org/wiki/ECMAScript] — Java повлиял на ECMAScript, не наоборот,
смотрим (английскую)[https://en.wikipedia.org/wiki/ECMAScript] — Java повлиял на ECMAScript, не наоборот. Так что сравнение в полной мере корректное.


Напрасно вы так. Не важно, какой там рынок, я вот ещё полгода назад видя ситуацию с окончанием поддержки Firefox пытался написать простой веб-браузер, который обрабатывал бы HTML, CSS и исполнял JS код, и при этом нормально работал бы на Win XP (и выводил там корректно сглаженный текст, с чем у того же Chrome большие проблемы были даже в версиях 22-49, а сейчас и вовсе который не поддерживается).

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


Вот здесь не понял. Что значит «более негативный прогноз»? И вообще, зачем начинать с openJDK, когда стандарт де-факто в отрасли, которым 90% людей пользуется — это JDK и JRE от Sun/Oracle? Она же бесплатная, верно? В чём там загвоздка, разве не логичнее использовать авторскую разработку, а не форк с неё, который к тому же непонятно, насколько совместим?

openJDK — 100% совместимая реализация языка + на неё рекомендовал для дальнейшего бесплатного использования переходить сам Оракл (в 11ой версии поменялось лицензионное соглашение для oracleJDK, резко ограничив бесплатные варианты использования). Так что эти доли сейчас сильно поменяются. А под "более негативным прогнозом" я подразумеваю то, что в оркаловой jdk, 6ой, кажется версии было написано именно о не-рекомендованности его использования.


Java в swing не поддерживает ClearType

-1
Java повлиял на ECMAScript, не наоборот
И что?)) Это отменяет тот факт, что Java и JS схожи по синтаксису? :)

Дорого, долго и профита нет.
Где из моих слов следует, что дорого и долго (хотя на самом деле, любой масштабный проект с нуля таким и бывает)? А про профит я вообще молчал. Да, может его и нет. Но это не значит, что в принципе нет пользователей, которые хотели бы иметь на XP исправный рабочий браузер. Притом удобный и без глюков, и поддерживающий современный JavaScript, чтобы сайты работали.

openJDK — 100% совместимая реализация языка
Но она написана не разработчиком языка и JVM, а другими людьми. То есть это тоже JVM, но другая. Совместимость — это очень здорово, но зачем?

в 11ой версии поменялось лицензионное соглашение для oracleJDK, резко ограничив бесплатные варианты использования
Кому вообще нужна 11-ая версия, если 6-ая и 7-ая работают прекрасно, и там с лицензией всё норм? Что там жизненно необходимого добавили?

А под «более негативным прогнозом» я подразумеваю то, что в оркаловой jdk, 6ой, кажется версии было написано именно о не-рекомендованности его использования.
Спасибо, теперь понял.

Java в swing не поддерживает ClearType
Но ведь при выборе нативного L&F поддерживает… На глаз же видно. Могу даже скрины покидать. И программный код, чтобы было видно, что там не AWT юзается.
+1
И что?)) Это отменяет тот факт, что Java и JS схожи по синтаксису? :)

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


Где из моих слов следует, что дорого и долго (хотя на самом деле, любой масштабный проект с нуля таким и бывает)? А про профит я вообще молчал. Да, может его и нет. Но это не значит, что в принципе нет пользователей, которые хотели бы иметь на XP исправный рабочий браузер. Притом удобный и без глюков, и поддерживающий современный JavaScript, чтобы сайты работали.

Я вам писал о том, что поддерживать работоспособность ПО в не поддерживаемых версиях вендором ОС стоит дополнительных денег… и если там полтора землекопа пользователей — то и заморачиваться этим никто не будет, потому что "долго, дорого и профита от такой работы нет". Ну не будете же вы сейчас выпуская приложуху под андроид 6-7-8 делать, чтобы и на какой-нибудь устаревшей версии а-ля 2.1 оно запускалось!


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

Вас, наверное, это удивит, но большую часть OpenJDK пишут те же люди, что и OracleJDK. "А зачем" — ну теперь это будет следствием нового лицензионного соглашения.


Кому вообще нужна 11-ая версия, если 6-ая и 7-ая работают прекрасно, и там с лицензией всё норм? Что там жизненно необходимого добавили?

Вы будете сильно расстроены, если узнаете, что желающих работать с 6-7ой версией постепенно уменьшается и они уходят сильно на задний план? Ещё пару-тройку лет будет ходовой версией 8ка, но после она тоже уйдёт со сцены. И не учитывать это в планах… ну вредно для тех, кто собирается использовать платформу и дальше.


Но ведь при выборе нативного L&F поддерживает… На глаз же видно. Могу даже скрины покидать. И программный код, чтобы было видно, что там не AWT юзается.

Не знаю, насколько оно там поддерживает, и какова реализация данной фичи, вот только ClearType, если мне память не изменяет — виндовая фича и без кучи лицензионных проблем не может быть запущена в том же линуксе… Вполне возможно, что вы оказались правы в своём предположении, что нативный L&F использует нативный UI...

0
в не поддерживаемых версиях вендором ОС
Там риски по безопасности сильно растут (особенно если это что-то антивирусное или связанное с передачей данных в облако). В своё время Dropbox вроде именно поэтому поддержку XP прекратил. А насчёт цены разработки — я бы всё же не согласился, не факт, что там всё становится прямо уж в разы сложнее. Что-то наоборот под старые ОС делать проще даже…

Ну не будете же вы сейчас выпуская приложуху под андроид 6-7-8 делать, чтобы и на какой-нибудь устаревшей версии а-ля 2.1 оно запускалось!
Ну не знаю. Я вот уже года 3 планирую прочитать книжку про программирование под Android. Как только научусь что-то более-менее писать — Android 2.3 точно буду поддерживать. Тем более у самого он стоит.

Вас, наверное, это удивит, но большую часть OpenJDK пишут те же люди, что и OracleJDK.
А, ну это сильно меняет ситуацию тогда :)

Вы будете сильно расстроены, если узнаете, что желающих работать с 6-7ой версией постепенно уменьшается и они уходят сильно на задний план?
А почему? Если кому-то так нужны стримы и лямбды (хотя имхо это нужно редко) — ну есть 8-ая в конце концов. Но в основном и 7-ой хватает за глаза и за уши (ладно, с 6-кой я погорячился, она не умеет неблокирующий ввод-вывод толком, и менее гибко работает, например, с атрибутами файлов). В 7-ой версии с этим всё на порядок лучше и приятнее.

если мне память не изменяет — виндовая фича и без кучи лицензионных проблем не может быть запущена в том же линуксе…
Так оно только в системном L&F — и естественно, работает только на винде. Не вижу причин, почему использовать Windows Forms или WPF можно (при этом разработчик приложения ничего не отчисляет Microsoft за возможность выводить их контролы на экране), а Swing — нет. Если JVM дёргает обычный Windows API в этом случае, то никакие лицензии не нарушены, вроде.
0
Какая разница джависту, че там у хохлов как там в JS? Это идеальный язык, из которого все должны тащить «паттерны»? Вроде бы наоборот.
А какие у вас там привычки — дело ваше и тех бедолаг, что вынуждены поддерживать ваш код. В дискуссии о best practices они вообще не являются аргументом.
0
А какие у вас там привычки — дело ваше и тех бедолаг, что вынуждены поддерживать ваш код.
Не вижу никакой проблемы в поддержке кода с циклом for на индексах вместо цикла forEach. Вы какую-то проблему из пальца высасываете, честное слово…
0
Согласен, на фоне непонимания, зачем нужен Set и прочего, цикл for — вообще не проблема.
0
Вы вот написали «какая разница джависту». Так вы по себе всех меряете. Я вот вообще не джавист, у меня JS основной язык. В последний раз на Java писал пару небольших проектов летом 2015 и в начале 2016.

Мне по идее вообще не стоило встревать — но я лишь хотел сказать, что есть некоторое количество людей (не все и не большинство), которые Vector всё ещё используют. Кстати, если он так ужасен, почему его не выпилят? Ах да, знаменитая обратная совместимость. Ну так не вопрос, можно было начиная с некоторой версии в фоне, незаметно для программиста, заменять его на ArrayList, а в консоль при компиляции выводить об этом предупреждение. Но тем не менее он зачем-то оставлен? Очень нелогично.
0
Даже не надейтесь, что буду отвечать по существу. В другой ветке я уже написал, что раскусил вас: вы тролль, причем очень умелый: несколько человек, включая меня, повелись. Ну просто я не верю, что человек может на полном серьезе написать всю ту чушь, которую мы тут видели в вашем исполнении. А еще мне хочется верить в лучшее. Потому что если вы не тролль, то это совсем печально. И плохо тут не то, что вы чего-то не знаете, а то, что, вместо самообучения, спорите в интернете со специалистами на темы, в которых не разбираетесь. Речь не о том, чтобы верить нам на слово. Просто если разработчики JDK говорят, что не надо использовать Vector или Hashtable, не стоит с порога отвергать это мнение в стиле tac (в смысле, все пидорасы тупые, а я д'Артаньян Эйнштейн). Разберитесь, почему они так говорят, что рекомендуют использовать вместо этого и почему.
0
Просто если разработчики JDK говорят, что не надо использовать Vector или Hashtable
Можно ссылку на цитату разработчиков, где они такое говорят? И аргументацию, почему эти коллекции не были удалены из JDK?

уже написал, что раскусил вас: вы тролль, причем очень умелый
Ну-ну.

Потому что если вы не тролль, то это совсем печально.
Да ладно? По-моему, всё ок :)

вместо самообучения
Не вместо. Как только мне придётся писать в следующий раз многопоточное приложение — я обязательно ознакомлюсь и с ConcurrentHashMap, и с общей теорией на тему грамотной синхронизации, и если надо будет — с чем угодно. И постараюсь найти лучшее решение, чем тупо пихать всюду Vector и Hashtable (тем более, на сто процентов это не спасёт).
0
использует циклы вместо итераторов

Кстати, на минутку — есть какой-то аргумент, чем итератор лучше цикла for? Тем, что он сохраняет стейт коллекции в момент начала обхода? Так он ничего не сохраняет, там при попытке изменения коллекции исключение выкинет…
0
Полная глупость. Вы сами это хотя бы понимаете? Оптимизация никогда не бывает преждевременной. Она либо окажется полезной (если приложение и объём данных будут расти), либо просто никак не скажется на качестве работы. Но ухудшить ситуацию — она не может. Если не брать случаи серьёзного говнякания архитектуры ради производительности, как Вы верно заметили.
+2
Она ухудшает ситуацию тем, что ресурсы, которые могли быть выделены на улучшение или создание чего-то, что улучшает работу, отдаются на то, что никак на неё не влияет.
0
Но может повлиять в дальнейшем при возрастании объёма данных в системе (или при усложнении логики другого компонента, что уже не так очевидно, но тоже возможно).

на улучшение или создание чего-то
Есть в жизненном цикле продукта стадии, когда пилить новые фичи пачками ежедневно уже не нужно. Как раз тогда и есть смысл заниматься оптимизацией (но честно говоря, лучше делать её сразу, пока всё в памяти свежо и ты точно знаешь, как в твоём коде что работает). Имхо.
0
Вы когда-нибудь занимались разработкой и поддержкой мало-мальски сложных высоконагруженных систем? Использовали профайлеры? Искали узкие места?
0
К сожалению, нет. Но ведь очевидно, что чтобы эти самые узкие места не возникали (точнее, возникали как можно более нескоро и в малом количестве), лучше как раз сразу писать оптимальный код, а не оптимизировать тогда, когда уже «всё плохо и еле ворочается»?
0
К сожалению, нет.

На этом можно закончить. Было бы «да» — были бы очевидны совершенно другие вещи.
-1
Меньше лишнего кода, меньше возможностей для выстрела себе же в голову.

А где тут можно выстрелить себе в голову? Тут же всё тривиально.

Если человек не совсем дуб, то при итерации он в самом начале выделит элемент коллекции в переменную, аля var test = testList.get(i);

Верно. Но если там в теле цикла одна строчка — то даже этого может быть не нужно.

Зачем вручную прописывать создание переменной и использовать for(;;) конструкцию, когда есть более лаконичный foreach

Более лаконичный, но менее броский при беглом сканировании кода глазами (всё-таки эти i-шки хорошо и сразу видны, а вот вариант с двоеточием — имхо, не очень заметен).

и увеличит шансы случайно пропустить выстрел или логическую ошибку в виде testList.get(j) или testList.get(i-j)

Эм, что? Откуда тут j вообще? Это уже более сложный вариант алгоритма, с двумя вложенными циклами, и вот там действительно индексы могут быть иногда нужны. Но я вообще не его рассматривал :)

когда в языке есть куда более подходящие конструкции

Ну есть ещё вариант с итераторами, но он более многословный.
+1
А где тут можно выстрелить себе в голову? Тут же всё тривиально.

Эм, что? Откуда тут j вообще? Это уже более сложный вариант алгоритма, с двумя вложенными циклами, и вот там действительно индексы могут быть иногда нужны. Но я вообще не его рассматривал :)

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

Более лаконичный, но менее броский при беглом сканировании кода глазами (всё-таки эти i-шки хорошо и сразу видны, а вот вариант с двоеточием — имхо, не очень заметен).

Дело привычки больше. Как по-мне, оба заметны в равной степени. Что там for(smth:smth), что там for(smth;smth;smth).

Ну есть ещё вариант с итераторами, который работает и в Java 6, и в Java 5, но он более многословный.

foreach это и есть сахар над итераторами, насколько я помню.)
А в современной версии есть ещё вариант итерирования через лямбды и стримы.
Каждой задаче свой инструмент.
Для простого итерирования — foreach, для замысловатой логики с индексами — for(;;), для фильтрации по значениями, сортировки — stream, для однострочных действий — .forEach через лямбды.
0
j в данном случае просто визуально похожая буква(а не вложенный цикл)

Что?..) Во-первых, не настолько похожа, чтобы перепутать (если шрифт нормального размера). Во вторых, такой переменной может просто не быть в данном методе определено — тогда сразу красным IDE подчеркнёт такой код.

Что там for(smth:smth), что там for(smth;smth;smth).

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

А в современной версии есть ещё вариант итерирования через лямбды и стримы.

Это только начиная с Java 8. Если я пишу на 6-ой — к сожалению, не вариант. Хотя почитать всё равно стоит, чтобы иметь представление, давно собираюсь)
0
foreach это и есть сахар над итераторами, насколько я помню

Кстати, забыл добавить: выше комментаторы указывали, что создание итератора — это лишние накладные расходы, и в некоторых случаях они могут быть существенными. Тогда зачем использовать foreach вместо for (то, что это сахар — уже замедлит компиляцию в байт-код как минимум на копейки, плюс само наличие итератора, которое может быть нежелательным)? Не говорите только опять про опечатки в буквах, такие ошибки — это даже не уровень школы, серьёзный программист никогда их не допустит (да и IDE не даст).
0
А вам не кажется, что у вашего варианта читаемость сильно ниже при беглом просмотре кода? Или это у меня только такое, субъективное?

Скорее всего субъективное. Общепринятое мнение, что вариант s-kozlov читается лучше.


Насчёт линейного времени — зависит от того, что за коллекция.

В 99% случаев использование LinkedList в Java там, где обозначен интерфейс List — ошибка, так что проблемы с линейным доступом скорее всего не будет.


При маленьких объёмах данных — это вообще, имхо, не суть важно.

Внезапно при маленьких данных становится важно, что использовать — foreach, или стандартный for. В этом случае при использовании foreach накладные расходы на него могут оказаться сравнимыми со временем обхода коллекции.


Если очень хочется подстраховаться с этим моментом — правильнее использовать итератор.

В foreach в джаве под капотом именно итератор ))


Самое главное — я не понимаю, почему для вас стандартный заголовок цикла for(), который, кстати, одинаков вообще для любого C-подобного языка — это «отвлекаться на индексы».

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

0
Внезапно при маленьких данных становится важно, что использовать — foreach, или стандартный for. В этом случае при использовании foreach накладные расходы на него могут оказаться сравнимыми со временем обхода коллекции.

Спасибо! Не знал про этот момент раньше)

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

У интерфейса List есть метод listIterator, который вернёт такой итератор, у которого есть метод remove, который удалит элемент, на котором стоит итератор. Для LinkedList сложность вызова метода remove у итератора будет константной, а у ArrayList — линейной.


(а вот обход с индексами с корректировкой переменной после каждого удаления — без проблем).

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


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

Вызов list.remove(index) будет иметь линейную сложность, независимо от того, чем является list. В случае с ArrayList — для удаления элемента надо будет сдвинуть следующие элементы влево, а в случае с LinkedList — нужно будет сначала найти элемент по индексу.

0
у которого есть метод remove, который удалит элемент, на котором стоит итератор

Спасибо, не знал про такое.

В случае с ArrayList — для удаления элемента надо будет сдвинуть следующие элементы влево

А зачем он их двигает сразу? Теоретически, можно было бы оставлять пропуски… Ну понятно, в общем там всё как в обычном массиве работает. С Vector та же история?

Для LinkedList сложность вызова метода remove у итератора будет константной, а у ArrayList — линейной.

Так подождите. Если у меня вектор — получается, мне всё равно, чем удалять? Раз всё равно удаление выполняется за линейное время. Я просто делал это через индексы в своём проекте.
+1
А зачем он их двигает сразу?

Чтобы гарантировать константное время доступа к элементу листа по индексу. Если мы оставим пропуски, для поиска элемента по индексу придётся перебирать элементы коллекции.


С Vector та же история?

С Vector то же самое, только Vector использовать нельзя. Это legacy класс, использование которого пагубно сказывается на производительности.

-1
Что у него не так с производительностью? И никакой он не legacy. Скиньте пруф этого «гениального» утверждения.

Vector и ArrayList всегда идут в паре, и применяется то, что нужно, в зависимости от ситуации. Vector внутри синхронизирован, если что. В многопоточном коде это критично.
0
Что у него не так с производительностью? И никакой он не legacy. Скиньте пруф этого «гениального» утверждения.

Будем обсуждать в соседней ветке, ок?

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

За счет чего она может быть ниже? Очевидности этого кода позавидовал бы сам Капитан.
Насчёт линейного времени — зависит от того, что за коллекция.

Ну и зачем создавать себе зависимость от этого там, где она не нужна?
При маленьких объёмах данных — это вообще, имхо, не суть важно

Если более эффективный код проще, вменяемый программист напишет его независимо от объема данных.
Вообще вариант с индексами, если они сами по себе не нужны в теле цикла, однозначно хуже, по всем показателям. Зачем вообще с ним сравнивать?
Если очень хочется подстраховаться с этим моментом — правильнее использовать итератор.

Вы давно писали на Java? Foreach — синтаксический сахар над итератором.
я не понимаю, почему для вас стандартный заголовок цикла for(), который, кстати, одинаков вообще для любого C-подобного языка — это «отвлекаться на индексы»

А я не понимаю, с чего бы мне писать на Java как на абстрактном си-подобном языке, не используя возможности Java.
0
Ну и зачем создавать себе зависимость от этого там, где она не нужна?

Выше уже написали, что ничего не меняется при удалении (всё будет зависеть от типа коллекции при любом подходе). А при чтении по индексу — в случае Vector и ArrayList тоже в общем-то нет разницы. Но да, тот подход лаконичнее, писать меньше.

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

Он не хуже. Он эквивалентен. Кроме случае с LinkedList и доступа к элементу за линейное время.

Foreach — синтаксический сахар над итератором.

Нет, совсем недавно. Я просто не очень привык применять эту форму for с двоеточием

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

Ну например потому, что с индексами визуально нагляднее, я выше уже писал, почему. А ещё потому что привычка из JavaScript — там for через индексы работает существенно быстрее, чем for...in.
0
Выше уже написали, что ничего не меняется при удалении

Изначально об удалении речи не шло.
Он эквивалентен. Кроме случае с LinkedList и доступа к элементу за линейное время.

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

Субъективно. У меня наоборот.
А ещё потому что привычка из JavaScript — там for через индексы работает существенно быстрее, чем for...in.

В общем случае это плохая привычка — писать на языке А как на Б.
0
Изначально об удалении речи не шло.

Но это часто необходимая операция! Как можно её не рассматривать?

Второе утверждение противоречит первому.

Там выше кто-то говорил, что LinkedList редкий случай. Но я вообще несколько запутался. Вы не могли бы ещё раз прояснить, в каких ситуациях обход по индексу будет медленнее, чем foreach или итератор? Такой кейс вообще в природе существует?

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

С последним утверждением — полностью согласен. Проблема в том, что цикл for — это не «фишка» только JavaScript. Такие циклы можно встретить и в программах на C, C++, ActionScript и PHP, как минимум. То есть это общепринятая конструкция. Да, в Java могут быть лучшие способы итерирования, и не только в Java. Но писать код, понятный программисту на любом языке — имхо, не есть минус…
0
Но это часто необходимая операция!

Судя по моей практике (а это не только лабораторки в универе), это ни фига не часто необходима операция, по крайней мере, по сравнению с итерированием и добавлением в конец.
Вы не могли бы ещё раз прояснить, в каких ситуациях обход по индексу будет медленнее, чем foreach или итератор? Такой кейс вообще в природе существует?

LinkedList. Существует. И вообще главный недостаток for не в сферической производительности в вакууме, а в неуниверсальности и зашумленности низкоуровневыми деталями.
поскольку если у любой коллекции есть метод get() — он сделан не просто так, а именно ради того, чтобы нас не беспокоил тип коллекции при обходе.

Сами-то поняли, что написали? Где метод get() у java.util.Set?
Но писать код, понятный программисту на любом языке — имхо, не есть минус…

Зачем?
0
LinkedList. Существует.
Я вот в своей практике (пусть она и не такая обширная, как у вас) ни разу его не использовал. Зачем оптимизировать код под коллекцию, которой никогда не пользуешься и пользоваться не планируешь? Опять же, я не говорю про работу в большом проекте в команде, я говорю про собственный проект, где 1 или максимум 2 разработчика.

по крайней мере, по сравнению с итерированием и добавлением в конец
Соглашусь. Но всё-таки и она довольно часто нужна.

Сами-то поняли, что написали? Где метод get() у java.util.Set?
А я не знаю, почему его не сделали. Множествами я тоже не пользуюсь. Как по мне, это очень неудобная коллекция — например хотя бы потому, что для её обхода необходим итератор (то есть нельзя проитерироваться по ней в цикле for, что, я настаиваю, является самым интуитивным подходом). И не сделав метод get (хотя да, он не имеет смысла, потому что у элементов нет уникальных ключей, а если они будут, то это будет уже хэш-таблица), разработчики JDK серьёзно подпортили универсальность интерфейса, т.е. независимость реализации от типа используемой фактической коллекции.
0
Я вот в своей практике (пусть она и не такая обширная, как у вас) ни разу его не использовал. Зачем оптимизировать код под коллекцию, которой никогда не пользуешься и пользоваться не планируешь? Опять же, я не говорю про работу в большом проекте в команде, я говорю про собственный проект, где 1 или максимум 2 разработчика.

Что вы используете в своих pet projects — ваше личное дело, и я не собираюсь навязывать вам стиль разработки. Но вы же выходите «в люди» и начинаете спорить, противопоставляя общепринятым best practices свои личные привычки, выработанные на тех самых pet projects.
А я не знаю, почему его не сделали.

Да хотя бы потому, что у множеств нет порядка элементов, соответственно, не имеет смысла запрос «дай мне n-й элемент».
разработчики JDK серьёзно подпортили универсальность интерфейса, т.е. независимость реализации от типа используемой фактической коллекции

Независимость реализации обхода коллекции портите вы, упершись в свой for и не желая писать на Java как на Java, а не урезанном JS. У тех, кто использует for-each, никаких проблем с независимостью реализации нет.
0
Что вы используете в своих pet projects — ваше личное дело
Что такое pet projects? Типа проекты, где автор сам себе единственный разработчик?

А что, бывают какие-то ещё проекты (ну если не брать участие в серьёзном Open Source типа Chromium/Firefox/VLC/etc.)? Как бы 80-90 процентов проектов — именно такие. Редко когда приходится привлекать кого-то ещё себе в помощь.

Да хотя бы потому, что у множеств нет порядка элементов, соответственно, не имеет смысла запрос «дай мне n-й элемент».
Я в курсе, что такое множество, спасибо, Капитан Очевидность :) Я лишь про то, что универсальность страдает в итоге из-за того, что у множества нельзя попросить вернуть элемент методом get (я не говорю, что на вход непременно должен приниматься порядковый номер, у хэш-таблиц вон принимается ключ, и ничего).

У тех, кто использует for-each, никаких проблем с независимостью реализации нет.
А, простите, через forEach можно ещё и множества обходить? Вот этого не знал. Хотя, раз выше написали, что там итератор создаётся «под капотом», то всё логично.

Да, подход с forEach лаконичнее и универсальнее (на примере списков и множеств доказали). Согласен со всеми.

Но всё-таки множества используются очень редко. Да и списки — не так чтобы очень часто.

Но если гнаться за идеальным кодом — да, наверное forEach лучше.

Но всё равно Вы не последовательны — выше Вы вон утверждали, что плохо делать оптимизацию раньше времени (оптимизированный код всяко лучше неоптимизированного). То есть там Вы не хотите стремиться к идеальному коду. А тут что иначе обстоит, вроде всё то же самое, только речь не о производительности, а о краткости конструкции и её максимальной «безопасности» в случае смены типа коллекции. Почему для Вас эти два аспекта важнее скорости работы приложения? Это глупо, особенно учитывая, как редко меняют тип коллекций на практике в живом проекте.
0
А что, бывают какие-то ещё проекты (ну если не брать участие в серьёзном Open Source типа Chromium/Firefox/VLC/etc.)?

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

А, простите, через forEach можно ещё и множества обходить? Вот этого не знал.

Но всё-таки множества используются очень редко. Да и списки — не так чтобы очень часто.

Почему для Вас эти два аспекта важнее скорости работы приложения?

Блин, да это ж всё троллинг был! Браво, апплодирую стоя!
0

Ну и как бы у get(i) тоже никто не гарантирует константную сложность, но не в этом суть. Плохого то, что этот код еще нужно читать и поддерживать. В Java 8 коллекции итерируются при помощи стримов или при помощи цикла for-each, который был введен еще в 2004 году, а до этого использовались итераторы вместо индексов. Индекс при итерировании используется только с ArrayList, когда итерация идет не по-порядку, и в тех случаях, когда значение индекса используется в цикле.