All streams
Search
Write a publication
Pull to refresh
12
0.2

Пользователь

Send message

Выдалась минутка почитать внимательнее. Вот так нет никакого вывода:

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE '
%h = map {(join("", sort split//) => [$_])} @F;
say join(", ", @$_) . "\n" for grep {@$_ > 1} values %h
'
$ 

потому что:

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE '
%h = map {(join("", sort split//) => [$_])} @F;
say "$_: @{$h{$_}}" for keys %h
'
адерс: среда
ксту: стук
имр: рим
акпр: парк
акму: мука
орст: трос
 $ 

В этом присваивании

%h = map {(join("", sort split//) => [$_])} @F;

значения по ключам перезаписываются, а не аккумулируются. Поэтому grep {@$_ > 1} values %h не пропускает ничего.

Вот так работает:

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE '
push @{$h{join "", sort split //}}, $_ for @F;
say join ", ", @$_ for grep {@$_ > 1} values %h
'
адрес, среда
кума, мука
карп, парк
мир, рим
рост, сорт, трос
куст, стук

И даже так:

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE '
say "Letters Cnt Words\n", "="x31;
push @{$h{join "", sort split //}}, $_ for @F;
printf "%5s %1d %s\n", $_, $#{$h{$_}}+1, qq([@{[join ", ", @{$h{$_}}]}])
  for keys %h
' \
| awk 'NR <= 2 { print; next } { print | "sort -k2 -n" }'
Letters Cnt Words
===============================
адерс 2 [адрес, среда]
 акму 2 [кума, мука]
 акпр 2 [карп, парк]
  имр 2 [мир, рим]
 ксту 2 [куст, стук]
 орст 3 [рост, сорт, трос]

Ура! :D


А дальше что? Книжку смог прочитать - сеньор, видос до конца осилил - мидл?

Есть ещё варианты!

Записался на одиннадцатимесячный курс программирования - стажёр. Написал на первом уроке "Привет, мир" - джун. Написал первый цикл - мидл. На последнем уроке усвоил лекцию о том, как проходить интервью - уверенно пишешь в CV "сениор". Правда, теперь нужны дополнительные ранги... На первой работе не уволили через месяц - рокстар. Продержался год - корифей. Два года - эпик. Три и больше - Легенда, обязательно с заглавной буквы. :)

P.S. А что, когда-то давным-давно наблюдал фирму, где сотрудников саппорта называли Инженерами Технической Поддержки, а каждый сотрудник отдела продаж был Менеджером Продаж. Правда, "инженерам" почему-то платили чуть больше минимума, "менеджерам" жилось существенно лучше, если получалось напродавать на хороший бонус.

Там специально набирают небольшие команды, полностью состоящие из сениоров, которым приходится работать с очень широким стеком языков (больше 20) и технологий. У менеджмента (в том числе и технического) есть очень чёткое понимание, что важно не дотошное знание наизусть, а умение быстро разрулить новую ситуацию. Которые там возникают каждый день. И устроить быстрый мозговой штурм через ChatGPT o1 в абсолютном большинстве случаев экономит время и позволяет не отвлекать других для использования в качестве "резиновой утки".
Ну и скучная рутина бывает, конечно.

В нормальных компаниях — это в каких? В формошлёпских?

Лично знаю компанию, успешно занимающуюся реализацией теории абстрактной интерпретации. Достаточно неформошлёпская? Они не заставляют пользоваться Copilot или ChatGPT и аналогами, но призывают пробовать и раздают лицензии.

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

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

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

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

Тестировали?

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -e '%h = map {(join("", sort split//) => [$_])} <>; print join(", ", @$_)."\n" for grep {@$_ > 1} values %h;'
 $ 
 $ 
 $ 
$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE 'say join "", sort(split //), " ", $_ for @F' \
| perl -CS -aE '%h = map {(join("", sort split//) => [$_])} <>; print join(", ", @$_)."\n" for grep {@$_ > 1} values %h;' \
| awk 'NR <= 2 { print; next } { print | "sort" }'
$
$

$ grep -vP '\W' /usr/share/dict/american-english \
| perl -pe 's/\n/ /' \
| perl -aE 'say join "", sort(split //), " ", $_ for @F' \
| perl -aE 'BEGIN {say "Letters    Cnt Words\n", "="x70} push(@{$an{$F[0]}}, $F[1]); END {printf "%8s %5d %s\n",  $_, $#{$an{$_}}+1, qq([@{[join ", ", @{$an{$_}}]}]) for keys %an}' \
| awk 'NR <= 2 { print; next } { print | "sort -k2 -n | tail -n 20" }'
Letters    Cnt Words
======================================================================
    alst     5 [alts, last, lats, salt, slat]
   aprst     5 [parts, sprat, strap, tarps, traps]
    arst     5 [arts, rats, star, tars, tsar]
   eerst     5 [ester, reset, steer, terse, trees]
  eilnst     5 [enlist, inlets, listen, silent, tinsel]
  eimrst     5 [merits, mister, miters, remits, timers]
   eimst     5 [emits, items, mites, smite, times]
   einrs     5 [reins, resin, rinse, risen, siren]
 eiprsst     5 [persist, priests, spriest, sprites, stripes]
   eoprs     5 [pores, poser, prose, ropes, spore]
   abest     6 [abets, baste, bates, beast, beats, betas]
   acert     6 [caret, cater, crate, react, recta, trace]
  adeprs     6 [drapes, padres, parsed, rasped, spared, spread]
   aelps     6 [lapse, leaps, pales, peals, pleas, sepal]
  aelpst     6 [palest, pastel, petals, plates, pleats, staple]
   aelst     6 [least, slate, stale, steal, tales, teals]
    opst     6 [opts, post, pots, spot, stop, tops]
  acerst     7 [carets, caster, caters, crates, reacts, recast, traces]
   aeprs     7 [pares, parse, pears, rapes, reaps, spare, spear]
   aerst     7 [aster, rates, stare, tares, taser, tears, treas]

\(^▽^)/

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE 'say join "", sort(split //), " ", $_ for @F' \
| perl -CS -aE 'BEGIN {say "Letters Cnt Words\n", "="x31} push(@{$an{$F[0]}}, $F[1]); END {printf "%7s %3d %s\n",  $_, $#{$an{$_}}+1, qq([@{[join ", ", @{$an{$_}}]}]) for keys %an}' \
| awk 'NR <= 2 { print; next } { print | "sort" }'
Letters Cnt Words
===============================
  адерс   2 [адрес, среда]
   акму   2 [кума, мука]
   акпр   2 [карп, парк]
    имр   2 [мир, рим]
   ксту   2 [куст, стук]
   орст   3 [рост, сорт, трос]

:)

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -aE 'say join "", sort(split //), " ", $_ for @F' \
| perl -CS -aE 'BEGIN {say "Letters Cnt Words\n", "="x31} push(@{$an{$F[0]}}, $F[1]); END {printf "%7s %3d %s\n",  $_, $#{$an{$_}}+1, qq([@{[join ", ", @{$an{$_}}]}]) for keys %an}'
Letters Cnt Words
===============================
   акму   2 [кума, мука]
   орст   3 [рост, сорт, трос]
  адерс   2 [адрес, среда]
   акпр   2 [карп, парк]
   ксту   2 [куст, стук]
    имр   2 [мир, рим]

(。◕‿‿◕。)

$ echo 'адрес карп кума куст мир мука парк рим среда стук рост сорт трос' \
| perl -CS -anE 'say $_, " ", join "", sort split //, $_ for @F' \
| sort -k2
адрес адерс
среда адерс
кума акму
мука акму
карп акпр
парк акпр
мир имр
рим имр
куст ксту
стук ксту
рост орст
сорт орст
трос орст

:D

Простите, но если мы вернемся к моему коду ...

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

Просто такой подход работает не везде - и это тоже совершенно нормально, что в кровавом энтерпрайзе другие подходы, куда более ориентированные на текучку кадров и на потребность в максимально быстрой реакции на происходящее. При этом объёмы кода таковы, что даже самые крутые и опытные спецы (которые способны умещать у себя в голове кучу логики, а ещё и часто доктора и профессора по информатике и прочим точным дисциплинам, т.е. априори далеко не глупые люди) очень ценят лаконичность и выразительность. Например - иногда потратить 15-20-30 и более минут времени на подбор подходящего имени для символа (переменной, функции, класса и т.д.) это нормальная история. Вы знаете, как трудно бывает найти специалиста и по используемым языкам, и по сопутствующим технологиям, и по предметной области? Часто практически невозможно, и бизнесу приходится идти на компромиссы по навыкам. И чтобы новые люди могли начинать приносить пользу в коде с минимальным временем обучения - просто необходимо относиться к коду с максимальной щепетильностью. Хех., у меня уже лет десять практически во всех IDE и редакторах включено отображение всех видов whitespace, это уже на уровне профдеформации.

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

Бывают, конечно, разные компании с разными командами и с разными подходами. Если повезёт попасть в реально хорошую команду, где все специалисты как минимум не хуже, а желательно лучше - этот опыт очень дорогого стоит. Есть большая разница между тем, как создавать скрипт в сто, тысячу строк, проект в 10 тысяч, систему в 100 и более тысяч и мультиязычную систему в сотни тысяч строк+.

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

В мире не существует книги, которая принесла бы больше вреда в индустрию, в сравнении с «Clean code».

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

Просто задам вопрос: а вы в этих ваших хайтеках используете докер, или там кубернетис?

Разумеется. А ещё "у нас есть такие приборы, но мы вам о них не расскажем" (с) - кучу всего используем.

А вы заглядывали в код докера, или ваша принципиальность по ревью распространяется только на бла-бла-бла на говноресурсиках типа хабра?

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

Поясню. Типичный случай (в моём опыте) - одновременно существуют легаси системы и параллельно с ними разрабатываются новые. Последнее происходит потому, что легаси хорошо выполняли свои задачи на ранних стадиях стартапа, но плохо справляются с темпами роста. На ранних стадиях обычно достаточно хорошие по оплачиваемой функциональности прототипы ради экономии времени волшебным образом превращаются в продакшен. Далее происходит быстрый рост всего - и довольно быстро оказывается, что легаси система с сотнями тысяч строк кода и функциями от сотен до десятков тысяч строк крайне плохо масштабируется на новые запросы. Увеличивается количество клиентов и обнаруживаются баги - и начинается бомбёжка тикетами, с которыми не справляется техподдержка. Увеличивается количество клиентов - и быстро растёт необходимость внедрения новых фич. И это не говоря уже о том, что подобный код крайне трудно адаптировать к горизонтальному масштабированию. Баги, фичи, скорость - всё это до определённой меры относительно быстро могут выполнять люди, изначально, извиняюсь, нахерачившие вот это всё. Пока они работают в фирме - они лидеры, т.к. это часто не столько программисты, сколько инженеры или учёные, реализующие свои - да, часто практически гениальные - идеи. Эти гениальные люди не умеют и/или не хотят разрабатывать код так, чтобы снижать стоимость входа для новых разработчиков. И они продолжают херачить как умеют. В какой-то момент, т.к. темп растущего бизнеса очень напряжённый, они выгорают и тем или иным образом уходят. Часто, толком не успев подготовить хотя бы одного сменщика (лично был знаком с системой, для высокоуровнего детального понимания работы которой (top-down), применимого в коде, нужно года два практически работать с ней в основном в режиме отладки (bottom-up) - нет человека, который бы мог или был бы готов провести адекватный онбоардинг).

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

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

Нет, конечно, в книжках же написано, что докер — это хорошо.

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

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

А вот делая код ревью, приходится взвешивать даже лишние пробелы - до сих пор есть люди, которые почему-то не могут в адекватные отступы. Они, обычно, не задерживаются, но если пропускать их код как есть, то, скажем, на 15 строк, которые могли бы восприняться за секунды, нужно уже тратить долгие минуты. То же и с декомпозицией. Верхнеуровневый код должен рассказывать историю своей работы в высокоуровневых терминах - так, чтобы было понятно, что он делает в целом, чтобы можно было работать в режиме top-down без необходимости читать все детали реализации. Это резко снижает порог вхождения и стоимость поддержки.

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

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

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

против «декомпозиции ради декомпозиции»

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

люди, которые не стесняются показывать код (и он у них в избытке есть)

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

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

"Богатые тоже плачут". :)

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

А как тут поможет именно инверсия зависимостей? Интерфейс объявить можно и без всякой инверсии.

Ищите в моём тексте слово "адаптеры".

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

И вот, нужно мне в бизнес-логике получить данные по ряду тразнакций и выдать некий результат. Для этого надо идти в базу данных. Без инверсии зависимостей я должен включить необходимые модули для работы с используемой базой данных и пользоваться их специфическими методами и их сигнатурами. Обращая зависимости, я объявляю зависимость от интерфейса, обязующегося реализовать ряд специфических методов. В классе адаптера, реализующего этот интерфейс, я работаю с конкретными модулями конкретных баз данных. Но если эти СУБД каким-нибудь образом обделались, и я хочу заменить их на другие, то в коде мне необходимо только написать новый адаптер, реализующий уже имеющийся интерфейс. А бизнес-логику трогать нет никакой необходимости. И так по отношению ко всем внешним зависимостям, включая фреймворки. Бизнес-логика - это ядро, которое не должно меняться при смене внешних зависимостей типа фреймворков или СУБД. В этом смысл инверсии зависимостей - чтобы твой персональный код не зависел от технических реализаций всякой внешней хрени, которой тьма, и предсказать изменения которой априори невозможно. И тогда, когда по любой причине тебе нужно поменять внешние зависимости - ты просто пишешь новые адаптеры, и подключаешь их вместо старых - И ВСЁ. Код твоей бизнес-логики НЕ ТРЕБУЕТ ИЗМЕНЕНИЙ.

Да и начальникам тоже такое говорить не стоит

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

А если стесняться, то ничего и не будет.

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

Но фильм конечно не русский.

Имя «Натали» тоже как бы не русское. Имя «Саша» может быть как русским, так и не русским

Специально для господ, интересующихся темой женско-русско-мужских имён есть классный сериал (конечно, не русский) - The Umbrella Academy. Вкраце: там русская девочка по имени Ваня взрослеет и решает, что она мальчик - и тогда она берёт себе имя Виктор. Твист в том, что реальная актриса тоже решает, что она мальчик, и меняет имя Эллен на Эллиот. Не знаю, в какой последовательности, смотрел сериал не из-за этого и сам был сильно озадачен развитием событий. Но там явно знают толк в именах... :)

Information

Rating
2,447-th
Registered
Activity

Specialization

Fullstack Developer, Legacy Code Tamer
Senior
From 100,500 $
Perl
PHP
JavaScript
Python
SAST / DAST
Linux
Java
Bash
MariaDB
Docker