Дано: нужно отрисовать иерархию сотрудников в компании в виде интерактивного UI древа. Компании могут быть очень большими. Скажем пара тысяч человек. Данные уже загружены и готовы к отображению.
Человек, который решал задачу, взял готовую библиотеку, которая умеет в виртуализацию. Всё подключил — всё работает. UI в целом не лагает. Отзывчивый. Анимации красивые. Но каждый раз когда человек нажимает "+" на крупном звене мы наблюдаем некоторые тормоза. Плюс при изначальном отображении показан UI с индикатором загрузки.
Загрузки чего? Все данные уже на клиенте же. Копаем…
Визуально на экране помещается, скажем 30 пользователей, из пары тысяч. В профайлере вижу что рендерятся все тысячи. Стали разбираться — оказалось что виртуализатору нужно как-то узнать размеры всех нод. Поэтому он втихую рендерит всё и запоминает размеры. Упс. Т.е. виртуализация у нас как бы и есть и её как бы и нет.
Но размеры у всех нод согласно дизайну статичны. Достаточно их просто захардкодить и UI оживает мгновенно. Никаких более тормозов. Никаких индикаторов загрузки.
Однако осталась проблема с тем, что раз в секунду перерисовывается весь canvas. Почему? Проблема инвалидации ngrx селекторов. Хотя бы у одного пользователя online статус поменялся — всё перерисовываем. Даром что из тысяч визуально одновременно на экране видно пару десятков.
Решаем переносом логики вида "а онлайн ли данный юзер" в компонент отображения юзера. Проблема ушла.
Причём тут алгоритмы? А при том, что у меня как у reviewer-а этого модуля сразу моментально в голове всплыли все эти Big-O проблемы. Ну просто потому, что я сразу увидел что виртуализированное древо должно работать мгновенно, а оно чего-то там грузит. Там ведь нечему тормозить. Раз мы рисуем какие-то анимации загрузки, значит мы где-то сильно продолбались с асимптотикой. Обе вышеописанные проблемы были связаны с тем, что мы обрабатывали все ноды, там где нужно было обрабатывать только видимые.
Человек, который это реализовывал не увидел этих проблем и был уверен, что виртуализация уже работает. И даже был прав. Она работала. Но в полсилы. Он не знал, что можно сильно лучше. Он понимал что код обрабатывает все ноды, но он не знал что можно этого не делать. Логика вида "ну виртуализатор же должен посчитать все размеры" звучит логично. Никаких претензий к нему не имею, просто привёл в качестве живого примера как намётанный глаз мгновенно идентифицирует алгоритмические проблемы там, где их другие не видят и не знают что можно качественно что-то улучшить. Добавим к этому то что все эти loading индикаторы сами себя не заимплементят — получаем не только проблемы с производительностью, а ещё и проблемы с человекочасами.
По двум точкам график не строят. Но в целом у меня такие мысли:
Каждый выбирает себе компании, задачи, приоритеты по вкусу. Тысячу раз видел когда на вопрос руководства "А вот так сделать можно?" оно получало ответ "В теории да, но задача неподъёмная". Хотя с CS ответ был бы "через неделю будет готово" или "дайте мне денёк на поиграться и я отвечу".
Не зная инструмента, как правило, невозможно догадаться что его надо применить. Человек просто решает задачу как умеет. И думает при этом, что решил всё оптимально. Может даже премию получит за то, что всё ускорил в 10 раз (скажем индексы в СУБД добавил). А то что там можно было всё на O(N) заменить человек в принципе представления не имеет. Но пол недели убьёт на красивую loading-анимацию, сервис отражения статуса выполняемой задачи и т.д.
Уже при постановке задачи народ исходит из "это невозможно (или мы не потянем)", а вот это уже готово в библиотеке Х. Подправим задачу так, чтобы библиотека Х прокатила.
Кто-то десятилетиями перекладывает JSON и плачет про выгорание. А кто-то и спустя 15-20 лет тащится от работы и среди коллег прослыл фокусником, которому просто даёшь задачу и он просто её выполняет. Вне зависимости от сложности. Сам проведёт анализ, найдёт решение, отладит, напишет тесты и т.д.. Потом ещё по согласованию с руководством выложит код либы в open source под логотипом компании.
Кто-то в принципе ударяется в познание того, как его рабочие инструменты работают под капотом. А там чего только нет. И побитовая магия, и всякие хипы, LRU кеши, rate limiter-ы разных мастей, в хайлоаде вообще половина Кнута в том или ином виде реализована. И вот когда такой человек начинает отвечать за core часть всех важных homemade инструментов компании, у него может собственная версия хоть даже LinkedList-а завестись.
Ну и т.д.
Вспомнилось ещё. Бинарный поиск применил когда отрисовывал в школьном приложении математические графики. Нужно было для поиска экстремумов заданной функции. Причём бинарный поиск не по массиву, а в рамках бесконечного углубления в дробность чисел. Впрочем это уже нюанс.
Я знаю. Просто lightin2 упомянул что мол структура простая и пишется слёту. Я бы поспорил. Я помнится долго её отлаживал. На собесе я бы сильно удивился, если бы меня заставили её писать. Это изврат.
Heap пригодился когда писал свою версию React-а. Нужно было сортировать древо инвалидированных (= требует rerender-а) компонентов. Обычная сортировка отпадает, т.к. эта коллекция изменяется в процессе (инвалидация context provider-а инвалидирует всех consumer-ов).
Причём потребовалось комбинировать его с HashMap. После знакомства с LRU кешем решение пришло в голову моментально.
LRU cache использую обильно уже во 2-й компании подряд. Гениальная штука.
Всякие обходы графов и деревьев пригождались сотни раз.
Наиболее интересные варианты были когда нужно было избегать circular reference-ов.
Топологическая сортировка пригодилась когда игрался с паттерном Observable
Trie пригодился когда писал подсветку найденного в тексте.
Linked List использовал несколько раз в кастомной реализации rate limiter-ов.
Конечные автоматы во всяких парсерах, интерпретаторах и иже с ними.
Мне попадалось довольно много medium задач, которые были сложнее ряда hard задач. Я часто тупо не понимал в чём была логика того, кто расставлял уровни. К примеру там есть задача Wiggle Sort (не помню точно название). Она medium. Я даже посмотрев решение мало что понял. В то время как были hard задачи уровня напиши небольшой парсер. 15 минут рутины и accepted. Видимо hard тупо за boilerplate.
Я бы рекомендовал сфокусироваться именно на тех hard задачах, которые самые ходовые. Чтобы не убивать газилион часов на всякие узкоспециализированные проблемы. На Leet Code есть такая сортировка.
Проблема hard задач в том, что там шибко много думать нужно. Уметь находить хитрые закономерности. Включать смекалку. Порой требуют наличия весьма непривычных навыков (например всякие побитовые хитрости уровня глубокого понимания представления отрицательных чисел в памяти). И т.д.. Для большинства разработчиков такое уже сильно за гранью применимости в продуктовой разработке. Как хобби, как спорт — отличная тема. Как практически применимые навыки — очень спорно. Ибо решение многих hard задач сродне пробиванию стены головой. А ведь в это время можно было бы покататься на лыжах, почитать книгу, поиграть в игры, поняньчиться с детьми, выспаться и т.д.
У меня hard задача из непривычной мне области легко отнимает 5+ часов. Ну это как-то перебор для for fun. После решения же, я как правило, не чувствую что стал умнее. Скорее понял конкретный corner case конкретной задачи. Это несколько демотивирует.
Для примера изюминка hard задачи может заключаться в том чтобы придумать псевдо-вершину в графе, которой нет в ТЗ, но она разблокирует применимость какого-нибудь алгоритма поиска минимального остова. И вот пока допетришь до этого (если вообще удастся) можно все мозги вскипятить. Но в другой задаче уже не будет такого lifehack-а. Там будет своя изюминка.
Ох. Т.е. моя KZ Activ симка, которая пока работает в Германии (вкл. раз в полгода), сразу умрёт если я прилечу домой? А чтобы зарегать её мне нужен сертификат, ради которого нужно ногами топать в ЦОН… Ох. Удобно придумали.
Оно бы и дальше не пахло. Но теперь это принудиловка по всему евросоюзу.
Только в N26
Тут вы что-то путаете. Там была точно такая же ситуация как и у коммерца.
Тут стоит уточнить: мгновенные платежи за деньги обе компании ввели давно. И 4г назад были в обоих банках (ну или 3г). Но вот бесплатными они стали где-то год назад из-за евро-закона.
Вводи команды, смотри что получается, в чём боль то?
Если следовать ему буква в букву, то может и заведётся. Имею ввиду даже версии либ взять ровно те, что указаны в мануале. Иначе уже возможны сложные коллизии зависимостей.
Чтобы следовать мануалу буква в букву желательно, чтобы он делал ровно то что вам нужно. Большинство мануалов отражают чьё-то конкретное видение проекта. Шаг влево, шаг вправо потребует разбирательств с используемыми технологиями. А это боль. Банально наладить условную цепочку postCSS, dartSass, и чего то ещё там в webpack подразумевало чёткую правильную последовательность с передачей индексов (иначе терялись sourceMap-ы). 99% мануалов было чем-то вроде сборки "манускриптов" без описания, что и зачем. 90% из них содержало ошибки (устаревшие поля, никогда не существовавшие поля, вредные советы и т.д.). В большинстве случаев это ещё было на JS, т.е. даже без типов. Проверялось уже путём сборки и проверки - упало не упало, сработало не сработало.
Сейчас с GPT стало полегче. И большая часть core вещей уже на Typescript.
Но ведь в этом и есть суть обучения - разобраться что к чему.
Ну новичкам куда важнее с полпинка начать писать код, а не заниматься конфигостраданиями. Разбираться в том, в чём вообще разбираться не хочется... Скажем если вы занимаетесь бизнесом, вы бы хотели уделять большую часть времени бизнес-делам, а не бухгалтерии и юриспруденции, так? Но у государства своё мнение по этому поводу :)
Но такими вещами новички ведь и не занимаются.
Отчего ж. Создал проект, реализовал всё что нужно. Вернулся к нему через год-полтора. Выяснил что всё устарело. NPM орёт об уязвимостях. Нужно обновить webpack, babel, eslint, lodash и иже с ними. Начинаешь этот процесс и... настроение стремительно ухудшается. Оказывается этот конструктор знатно рассползся.
И всего этого я не помню 15 лет назад, когда мы писали JS как пачку статических скриптов, которые и цепляли через <script/> к странице, а связь сущностей между скриптами проводилась через глобалки. Там реально можно было вкатиться в кодовую базу прямо сразу.
---
Просто для примера. Хочется иногда запустить typescript файл прямо из терминала. До недавних пор это была сплошная мука. Вместо "npm i -g tsc && tsc ./script.ts" мне приходилось много страдать. То оно не понимает ключевого слова "import", то оно не в курсе, что оно запущено в "nodejs" и весь файл красный, то ещё какая-нибудь проблема. Прямо спотыкалось на чём только можно и нельзя. 20 минут ковыряния "compilerOptions" и чьей матери - завелось. Каждое изменение словно заклинание. Не "левиОса" а "левиосА".
Наше комьюнити сделало всё гибким. Но при этом оно словно на изоленте.
Это когда опыт в этом уже есть. Если с нуля, то это прямо боль.
webpack уже никто не использует
На самом деле даже просто переехать на следующую мажорную версию webpack-а в сложных сборках было весьма не тривиально. Далеко не все неофиц. составляющие поспевали вовремя и там были прямо дичайшие проблемы с версиями, совместимостью и т.д.. Я пару раз проходил через это.
Это да. Современный CSS и HTML куда комфортнее. Но в те времена не было NPM и всяких сложностей с тем "как же блин всё это развернуть чтобы оно наконец показало мой hello world". Это на самом деле часто не тривиально (посмотрите на что жалуются коллеги из других областей, когда вынуждены временно переключиться на FE).
Мы ж теперь всё bundle-им, lint-им, format-им. Git Hooks, CI/CD, всякие AI валидаторы. На кривой козе (чистом CSS) в типовой проект не заедешь - нужно цеплять какой-нибудь CSS-modules, CSS-in-JS и иже с ними. HTML файлик не создашь. Нужно лезть разбираться с местным шаблонизатором. И т.д.. Ещё ни строчки не написал, а уже вспотел и возненавидел всю индустрию :)
Посмотрел level.fyi. Да, с зп получше, чем в Европе. В Google 200k$ уже на L4. Налоги судя по ответу perplexity немного ниже, чем в Германии. 200к это +- 10к на руки.
Хех. Раз уж вы предложили быть дотошным, то давайте будем ещё и честнее :)
Не "женат и третий класс" (какие-то непонятные слова для тех кто не в теме), а "если забрать у жены налогонеоблагаемую сумму в пользу мужа". Это кстати можно сделать и на 4-ом классе. Классы тут на самом деле не причём. Главное подаёте ли вы декларацию вдвоём или раздельно. Плюс жене при этом на работу выходить не стоит. А то эта математика начнёт рассыпаться.
Плюс на 5-ом классе можно и в депрессию уйти. Разводы в семьях эмигрантов регулярное явление. Отчасти от того что человек без работы и соц. связей в незнакомой стране кукушкой едет (не каждый, признаю).
Но да. Можно всяких "если" наковырять. Например хитрых налоговых вычетов.
Помучал GPT. Звучит прямо интересно. Если я правильно понял то там всего 24% налогов и до 600 евро соц. взносов (вкл. пенсию). После Германии это рай. Ещё и климат классный, тёплый. Правда, наверное, есть свои тонкости. Например 6 летний срок.
Вот ещё нетривиальный пример из практики:
Дано: нужно отрисовать иерархию сотрудников в компании в виде интерактивного UI древа. Компании могут быть очень большими. Скажем пара тысяч человек. Данные уже загружены и готовы к отображению.
Человек, который решал задачу, взял готовую библиотеку, которая умеет в виртуализацию. Всё подключил — всё работает. UI в целом не лагает. Отзывчивый. Анимации красивые. Но каждый раз когда человек нажимает "+" на крупном звене мы наблюдаем некоторые тормоза. Плюс при изначальном отображении показан UI с индикатором загрузки.
Загрузки чего? Все данные уже на клиенте же. Копаем…
Визуально на экране помещается, скажем 30 пользователей, из пары тысяч. В профайлере вижу что рендерятся все тысячи. Стали разбираться — оказалось что виртуализатору нужно как-то узнать размеры всех нод. Поэтому он втихую рендерит всё и запоминает размеры. Упс. Т.е. виртуализация у нас как бы и есть и её как бы и нет.
Но размеры у всех нод согласно дизайну статичны. Достаточно их просто захардкодить и UI оживает мгновенно. Никаких более тормозов. Никаких индикаторов загрузки.
Однако осталась проблема с тем, что раз в секунду перерисовывается весь canvas. Почему? Проблема инвалидации ngrx селекторов. Хотя бы у одного пользователя online статус поменялся — всё перерисовываем. Даром что из тысяч визуально одновременно на экране видно пару десятков.
Решаем переносом логики вида "а онлайн ли данный юзер" в компонент отображения юзера. Проблема ушла.
Причём тут алгоритмы? А при том, что у меня как у reviewer-а этого модуля сразу моментально в голове всплыли все эти Big-O проблемы. Ну просто потому, что я сразу увидел что виртуализированное древо должно работать мгновенно, а оно чего-то там грузит. Там ведь нечему тормозить. Раз мы рисуем какие-то анимации загрузки, значит мы где-то сильно продолбались с асимптотикой. Обе вышеописанные проблемы были связаны с тем, что мы обрабатывали все ноды, там где нужно было обрабатывать только видимые.
Человек, который это реализовывал не увидел этих проблем и был уверен, что виртуализация уже работает. И даже был прав. Она работала. Но в полсилы. Он не знал, что можно сильно лучше. Он понимал что код обрабатывает все ноды, но он не знал что можно этого не делать. Логика вида "ну виртуализатор же должен посчитать все размеры" звучит логично. Никаких претензий к нему не имею, просто привёл в качестве живого примера как намётанный глаз мгновенно идентифицирует алгоритмические проблемы там, где их другие не видят и не знают что можно качественно что-то улучшить. Добавим к этому то что все эти loading индикаторы сами себя не заимплементят — получаем не только проблемы с производительностью, а ещё и проблемы с человекочасами.
По двум точкам график не строят. Но в целом у меня такие мысли:
Каждый выбирает себе компании, задачи, приоритеты по вкусу. Тысячу раз видел когда на вопрос руководства "А вот так сделать можно?" оно получало ответ "В теории да, но задача неподъёмная". Хотя с CS ответ был бы "через неделю будет готово" или "дайте мне денёк на поиграться и я отвечу".
Не зная инструмента, как правило, невозможно догадаться что его надо применить. Человек просто решает задачу как умеет. И думает при этом, что решил всё оптимально. Может даже премию получит за то, что всё ускорил в 10 раз (скажем индексы в СУБД добавил). А то что там можно было всё на O(N) заменить человек в принципе представления не имеет. Но пол недели убьёт на красивую loading-анимацию, сервис отражения статуса выполняемой задачи и т.д.
Уже при постановке задачи народ исходит из "это невозможно (или мы не потянем)", а вот это уже готово в библиотеке Х. Подправим задачу так, чтобы библиотека Х прокатила.
Кто-то десятилетиями перекладывает JSON и плачет про выгорание. А кто-то и спустя 15-20 лет тащится от работы и среди коллег прослыл фокусником, которому просто даёшь задачу и он просто её выполняет. Вне зависимости от сложности. Сам проведёт анализ, найдёт решение, отладит, напишет тесты и т.д.. Потом ещё по согласованию с руководством выложит код либы в open source под логотипом компании.
Кто-то в принципе ударяется в познание того, как его рабочие инструменты работают под капотом. А там чего только нет. И побитовая магия, и всякие хипы, LRU кеши, rate limiter-ы разных мастей, в хайлоаде вообще половина Кнута в том или ином виде реализована. И вот когда такой человек начинает отвечать за core часть всех важных homemade инструментов компании, у него может собственная версия хоть даже LinkedList-а завестись.
Ну и т.д.
Вспомнилось ещё. Бинарный поиск применил когда отрисовывал в школьном приложении математические графики. Нужно было для поиска экстремумов заданной функции. Причём бинарный поиск не по массиву, а в рамках бесконечного углубления в дробность чисел. Впрочем это уже нюанс.
Я знаю. Просто lightin2 упомянул что мол структура простая и пишется слёту. Я бы поспорил. Я помнится долго её отлаживал. На собесе я бы сильно удивился, если бы меня заставили её писать. Это изврат.
У меня больше 100 строк вышло. Довольно дофига для собеса. Но, правда я думаю, он много где есть из коробки.
Heap пригодился когда писал свою версию React-а. Нужно было сортировать древо инвалидированных (= требует rerender-а) компонентов. Обычная сортировка отпадает, т.к. эта коллекция изменяется в процессе (инвалидация context provider-а инвалидирует всех consumer-ов).
Причём потребовалось комбинировать его с HashMap. После знакомства с LRU кешем решение пришло в голову моментально.
LRU cache использую обильно уже во 2-й компании подряд. Гениальная штука.
Всякие обходы графов и деревьев пригождались сотни раз.
Наиболее интересные варианты были когда нужно было избегать circular reference-ов.
Топологическая сортировка пригодилась когда игрался с паттерном Observable
Trie пригодился когда писал подсветку найденного в тексте.
Linked List использовал несколько раз в кастомной реализации rate limiter-ов.
Конечные автоматы во всяких парсерах, интерпретаторах и иже с ними.
То что удалось вспомнить за 5 минут
Мне попадалось довольно много medium задач, которые были сложнее ряда hard задач. Я часто тупо не понимал в чём была логика того, кто расставлял уровни. К примеру там есть задача Wiggle Sort (не помню точно название). Она medium. Я даже посмотрев решение мало что понял. В то время как были hard задачи уровня напиши небольшой парсер. 15 минут рутины и accepted. Видимо hard тупо за boilerplate.
Я бы рекомендовал сфокусироваться именно на тех hard задачах, которые самые ходовые. Чтобы не убивать газилион часов на всякие узкоспециализированные проблемы. На Leet Code есть такая сортировка.
Проблема hard задач в том, что там шибко много думать нужно. Уметь находить хитрые закономерности. Включать смекалку. Порой требуют наличия весьма непривычных навыков (например всякие побитовые хитрости уровня глубокого понимания представления отрицательных чисел в памяти). И т.д.. Для большинства разработчиков такое уже сильно за гранью применимости в продуктовой разработке. Как хобби, как спорт — отличная тема. Как практически применимые навыки — очень спорно. Ибо решение многих hard задач сродне пробиванию стены головой. А ведь в это время можно было бы покататься на лыжах, почитать книгу, поиграть в игры, поняньчиться с детьми, выспаться и т.д.
У меня hard задача из непривычной мне области легко отнимает 5+ часов. Ну это как-то перебор для for fun. После решения же, я как правило, не чувствую что стал умнее. Скорее понял конкретный corner case конкретной задачи. Это несколько демотивирует.
Для примера изюминка hard задачи может заключаться в том чтобы придумать псевдо-вершину в графе, которой нет в ТЗ, но она разблокирует применимость какого-нибудь алгоритма поиска минимального остова. И вот пока допетришь до этого (если вообще удастся) можно все мозги вскипятить. Но в другой задаче уже не будет такого lifehack-а. Там будет своя изюминка.
Ох. Т.е. моя KZ Activ симка, которая пока работает в Германии (вкл. раз в полгода), сразу умрёт если я прилечу домой? А чтобы зарегать её мне нужен сертификат, ради которого нужно ногами топать в ЦОН… Ох. Удобно придумали.
Оно бы и дальше не пахло. Но теперь это принудиловка по всему евросоюзу.
Тут вы что-то путаете. Там была точно такая же ситуация как и у коммерца.
Тут стоит уточнить: мгновенные платежи за деньги обе компании ввели давно. И 4г назад были в обоих банках (ну или 3г). Но вот бесплатными они стали где-то год назад из-за евро-закона.
Можно принять закон запрещающий такое e2ee
Анализировать трафик на предмет шифрования
Навещать особо бурных нарушителей и широко оглашать в СМИ их приговоры
Если следовать ему буква в букву, то может и заведётся. Имею ввиду даже версии либ взять ровно те, что указаны в мануале. Иначе уже возможны сложные коллизии зависимостей.
Чтобы следовать мануалу буква в букву желательно, чтобы он делал ровно то что вам нужно. Большинство мануалов отражают чьё-то конкретное видение проекта. Шаг влево, шаг вправо потребует разбирательств с используемыми технологиями. А это боль. Банально наладить условную цепочку postCSS, dartSass, и чего то ещё там в webpack подразумевало чёткую правильную последовательность с передачей индексов (иначе терялись sourceMap-ы). 99% мануалов было чем-то вроде сборки "манускриптов" без описания, что и зачем. 90% из них содержало ошибки (устаревшие поля, никогда не существовавшие поля, вредные советы и т.д.). В большинстве случаев это ещё было на JS, т.е. даже без типов. Проверялось уже путём сборки и проверки - упало не упало, сработало не сработало.
Сейчас с GPT стало полегче. И большая часть core вещей уже на Typescript.
Ну новичкам куда важнее с полпинка начать писать код, а не заниматься конфигостраданиями. Разбираться в том, в чём вообще разбираться не хочется... Скажем если вы занимаетесь бизнесом, вы бы хотели уделять большую часть времени бизнес-делам, а не бухгалтерии и юриспруденции, так? Но у государства своё мнение по этому поводу :)
Отчего ж. Создал проект, реализовал всё что нужно. Вернулся к нему через год-полтора. Выяснил что всё устарело. NPM орёт об уязвимостях. Нужно обновить webpack, babel, eslint, lodash и иже с ними. Начинаешь этот процесс и... настроение стремительно ухудшается. Оказывается этот конструктор знатно рассползся.
И всего этого я не помню 15 лет назад, когда мы писали JS как пачку статических скриптов, которые и цепляли через
<script/>к странице, а связь сущностей между скриптами проводилась через глобалки. Там реально можно было вкатиться в кодовую базу прямо сразу.---
Просто для примера. Хочется иногда запустить typescript файл прямо из терминала. До недавних пор это была сплошная мука. Вместо "npm i -g tsc && tsc ./script.ts" мне приходилось много страдать. То оно не понимает ключевого слова "import", то оно не в курсе, что оно запущено в "nodejs" и весь файл красный, то ещё какая-нибудь проблема. Прямо спотыкалось на чём только можно и нельзя. 20 минут ковыряния "compilerOptions" и чьей матери - завелось. Каждое изменение словно заклинание. Не "левиОса" а "левиосА".
Наше комьюнити сделало всё гибким. Но при этом оно словно на изоленте.
Это когда опыт в этом уже есть. Если с нуля, то это прямо боль.
На самом деле даже просто переехать на следующую мажорную версию webpack-а в сложных сборках было весьма не тривиально. Далеко не все неофиц. составляющие поспевали вовремя и там были прямо дичайшие проблемы с версиями, совместимостью и т.д.. Я пару раз проходил через это.
Он не один такой. Я тоже воспринимал эти термины наоборот. ChatGPT на вашей стороне:
Java: Always pass-by-value. But for objects, the “value” being passed is a copy of the reference.
You can mutate the object inside the function (since the reference points to the same heap object).
But if you reassign the reference, it won’t affect the caller’s variable.
Мне кажется терминология не очень удачно выбрана, т.к. позволяет разные трактовки.
Это да. Современный CSS и HTML куда комфортнее. Но в те времена не было NPM и всяких сложностей с тем "как же блин всё это развернуть чтобы оно наконец показало мой hello world". Это на самом деле часто не тривиально (посмотрите на что жалуются коллеги из других областей, когда вынуждены временно переключиться на FE).
Мы ж теперь всё bundle-им, lint-им, format-им. Git Hooks, CI/CD, всякие AI валидаторы. На кривой козе (чистом CSS) в типовой проект не заедешь - нужно цеплять какой-нибудь CSS-modules, CSS-in-JS и иже с ними. HTML файлик не создашь. Нужно лезть разбираться с местным шаблонизатором. И т.д.. Ещё ни строчки не написал, а уже вспотел и возненавидел всю индустрию :)
Посмотрел level.fyi. Да, с зп получше, чем в Европе. В Google 200k$ уже на L4. Налоги судя по ответу perplexity немного ниже, чем в Германии. 200к это +- 10к на руки.
Не соглашусь. Вы цены в Мюнхене видели? Особенно на жильё? :) Там никакой зарплаты не хватит.
Поэтому я и написал про честнЕЕ. Добавил, так сказать, критичного контексту.
Хех. Раз уж вы предложили быть дотошным, то давайте будем ещё и честнее :)
Не "женат и третий класс" (какие-то непонятные слова для тех кто не в теме), а "если забрать у жены налогонеоблагаемую сумму в пользу мужа". Это кстати можно сделать и на 4-ом классе. Классы тут на самом деле не причём. Главное подаёте ли вы декларацию вдвоём или раздельно. Плюс жене при этом на работу выходить не стоит. А то эта математика начнёт рассыпаться.
Плюс на 5-ом классе можно и в депрессию уйти. Разводы в семьях эмигрантов регулярное явление. Отчасти от того что человек без работы и соц. связей в незнакомой стране кукушкой едет (не каждый, признаю).
Но да. Можно всяких "если" наковырять. Например хитрых налоговых вычетов.
А мсье нас троллит прямиком из Дубая? :-)
Помучал GPT. Звучит прямо интересно. Если я правильно понял то там всего 24% налогов и до 600 евро соц. взносов (вкл. пенсию). После Германии это рай. Ещё и климат классный, тёплый. Правда, наверное, есть свои тонкости. Например 6 летний срок.