Финансовая сфера

Мониторинг медленных аллокаций

Как память выделяется мы выяснили, а вот что с этой информацией делать — пока нет.
Где-то выше я писал, что вся статистика (медленные аллокации, среднее количество refill’ов, количество аллоцирующих потоков, потери на внутреннюю фрагментацию) куда-то записывается.

Это куда-то — perf data, которая в конечном счете попадает в файл hsperfdata, и посмотреть на которую можно с помощью jcmd или программно с помощью API.

Другого способа для получения хотя бы части этой информации нет, но если вы пользуетесь Oracle JDK, то JFR умеет её показывать (пользуясь приватным API, недоступным в OpenJDK), причем сразу в срезе стек-трейсов.
Важно ли это? В большинстве случаев скорее всего нет, но вот например есть отличный доклад от Twitter JVM team, где замониторив медленные аллокации и покрутив нужные параметры, они смогли уменьшить время ответа своего сервиса на несколько процентов

Эксперименты

Теперь мы знаем, как создаются объекты и какими флагами можно этот процесс контролировать, самое время проверить это на практике. Напишем тривиальный бенчмарк, который просто создает java.lang.Object в несколько потоков, и покрутим опции JVM.Эксперименты запускались на Java 1.8.0_121, Debian 3.16, Intel Xeon X5675. По оси абсцисс — количество потоков, по оси ординат — количество аллокаций в микросекунду.

Получается вполне ожидаемо:

  • По умолчанию скорость аллокаций растет почти линейно в зависимости от количества потоков, и это как раз то, чего мы ожидаем от new. С ростом количества потоков становится чуть хуже, но это и неудивительно: если между аллокациями делать хоть какую-нибудь полезную работу (например, пользуясь Blackhole#consumeCPU), то нахлест аллокаций между потоками уменьшится, и скорость роста вернется к линейной.
  • Выключенный prefetch делает аллокации немного медленнее. В нашем бенчмарке мы просто перегружаем JVM аллокациями, и в реальных приложениях все может быть совсем по-другому, поэтому никаких выводов о пользе этой оптимизации делать не будем. Рецептов тут никаких нет, в конце концов всегда можно эту оптимизацию отключить и замерить для вашего конкретного приложения.
  • При выключенных аллокациях из TLAB’а все становится очень плохо: разница в два с половиной раза для одного потока — это цена вызова JIT -> JVM, а с увеличением количества потоков конкуренция за один единственный указатель лишь усиливается, и ни о какой масштабируемости речи не идет.

Ну и напоследок о пользе finalize, сравним аллокации из eden’а с аллокациями finalizable-объектов:

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

Новая стратегия — новое решение

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

Благодаря внедрению SAS Activity Based Management (ABM) бизнес-подразделения получили инструмент, с помощью которого они могут самостоятельно, без участия финансового департамента и ИТ-специалистов, видеть, как распределяются затраты, насколько эффективны банковские процессы, есть ли в них потенциал оптимизации. Такой подход породил постоянное активное обсуждение методики отнесения затрат, технического расчета, оптимальности сопровождающих процессов и компонентов. Итогом такой дискуссии является либо перераспределение расходов, либо изменение методики и получение результата, который более объективно отражает картину затрат.

TLAB 101

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

К счастью, в Java-машине есть сборщик мусора, который берет сложную часть работы на себя. В процессе сборки young generation все живые объекты перемещаются в survivor space, оставляя в eden’е один большой непрерывный регион свободной памяти.

Так как память в JVM освобождает GC, то аллокатору нужно лишь знать, где эту свободную память искать, фактически управлять доступом к одному указателю на эту самую свободную память. То есть, аллокация должна быть очень простой и состоять из пони и радуг: нужно прибавить к указателю на свободный eden размер объекта, и память наша (такая техника называется bump-the-pointer).

Память при этом могут выделять несколько потоков, поэтому нужна какая-то форма синхронизации. Если сделать её самым простым способом (блокировка на регион кучи или атомарный инкремент указателя), то выделение памяти запросто может стать узким местом, поэтому разработчики JVM развили предыдущую идею с bump-the-pointer: каждому потоку выделяется большой кусок памяти, который принадлежит только ему. Аллокации внутри такого буфера происходят всё тем же инкрементом указателя (но уже локальным, без синхронизации) пока это возможно, а новая область запрашивается каждый раз, когда текущая заканчивается. Такая область и называется thread-local allocation buffer. Получается эдакий иерархический bump-the-pointer, где на первом уровне находится регион кучи, а на втором TLAB текущего потока. Некоторые на этом остановиться не могут и идут еще дальше, иерархически укладывая буферы в буферы.

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

Выглядит слишком хорошо, чтобы быть правдой, поэтому воспользуемся PrintAssembly и посмотрим, во что компилируется метод, который создает :

Обладая о том, что в регистре всегда находится указатель на VM-ный поток (лирическое отступление: за счет такого инварианта thread-local’ы и работают очень быстро), понимаем, что это именно тот код, который мы и ожидали увидеть. Заодно заметим, что JIT-компилятор заинлайнил аллокацию прямо в вызывающий метод.

Таким способом JVM почти бесплатно (не вспоминая про сборку мусора) создает новые объекты за десяток инструкций, перекладывая ответственность за очистку памяти и дефрагментацию на GC. Приятным бонусом идет локальность аллоцируемых подряд данных, чего могут не гарантировать классические аллокаторы. Есть целое исследование про влияние такой локальности на производительность типичных приложений. Spoiler alert: делает все немного быстрее даже несмотря на повышенную нагрузку на GC.

Критерии выбора брокера

В России IPO проводятся крайне редко. Иногда в течение года не бывает даже одного (например, 2018 и 2019 годы), единицы выходят на американские рынки (например, в 2019 г. HeadHunter разместился на бирже Nasdaq). Новый 2020 г. “порадовал” только выходом на Московскую биржу компании “Совкомфлот”. Почему в кавычках? Потому что с момента размещения акций по 105 руб. за шт. 7.10.2020 цена снизилась до 96,3 руб. за шт. к 28.10.2020. К концу года готовится взлететь “Самолет” (крупнейший застройщик жилья).

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

Рассмотрим критерии выбора.

Надежность

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

Но в нашем списке будут и другие компании, которые зарегистрированы не в России и не имеют лицензии Центробанка: United Traders и Just2Trade. Этот момент надо учитывать, когда принимаете решение об инвестировании крупных сумм.

Необходимость получения статуса квалифицированного инвестора

До недавнего времени Фридом Финанс не предъявлял такого требования. Но на сегодня все посредники с российской юрисдикцией предоставляют доступ к первичным размещениям только квалифицированным инвесторам. Для тех, кто им не является, остаются только варианты иностранной юрисдикции. Есть брокеры (например, ВТБ), кто дает доступ к IPO на Московской бирже неквалам.

Минимальный порог входа

Разброс большой: от 50 до 300 000 $. При этом учитывайте, что далеко не все ваши деньги уйдут на покупку акций, потому что будет действовать аллокация – доля удовлетворения заявки. Она может быть минимальной – 0,5 %.

Количество предлагаемых IPO, в том числе за предыдущие периоды

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

Период lock-up

Напомню, что lock-up – это время, в течение которого нельзя продавать акции (около 3–6 месяцев). Некоторые посредники его не имеют вообще, другие разрешают избавиться от ценных бумаг до завершения “времени тишины”, но за дополнительную плату (10–15 %).

Комиссии

За ввод денег на брокерский счет и вывод их до истечения периода lock-up. Некоторые берут еще % с прибыли.

Обратная связь

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

Аллокация в C1

С размерами TLAB’ов разобрались. Чтоб далеко не ходить, поковыряем исходники дальше и посмотрим, как именно выделяются TLAB’ы, когда это быстро, когда медленно, а когда очень медленно.

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

Нас интересует два метода: , в котором описано аллоцирование объекта в TLAB’е и инициализация и , который исполняется, когда быстро выделить память не удалось.

Интересно посмотреть, всегда ли объект может быть создан быстро, и цепочка «find usages» приводит нас к такому вот комментарию в :

Из него становится понятно, что очень большие объекты (больше 128 килобайт по умолчанию) и finalizeable-классы всегда идут через медленный вызов в JVM. (Загадка — причем тут абстрактные классы?)
Возьмем это на заметку и вернемся обратно к процессу аллокации:

  1. tlab_allocate — попытка быстро аллоцировать объект, ровно тот код, что мы уже видели, когда смотрели на PrintAssembly. Если получилось, то на этом заканчиваем аллокацию и переходим к инициализации объекта.

  2. tlab_refill — попытка выделить новый TLAB. С помощью интересной проверки метод решает, выделять ли новый TLAB (выкинув старый) или аллоцировать объект прямо в eden’е, оставив старый TLAB:

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

  3. eden_allocate — попытка выделить память (объект или TLAB) в eden’е. Это место очень похоже на аллокацию в TLAB’е: проверяем, есть ли место, и если да, то атомарно, используя инструкцию , забираем себе память, а если нет, то уходим в slow path. Выделение в eden’е не является wait-free: если два потока попробуют аллоцировать что-то в eden’е одновременно, то с некоторой вероятностью у одного из них ничего не выйдет и придется повторять все заново.

JVM upcall

Если не получилось выделить память в eden’е, то происходит вызов в JVM, который приводит нас к методу . Перед самим вызовом проводится много вспомогательной работы — выставляются специальные структуры для GC и создаются нужные фреймы, чтобы соответствовать calling conventions, так что операция это небыстрая.
Кода там много и одним поверхностным описанием не обойдешься, поэтому чтобы никого не утомлять, приведу лишь примерную схему работы:

  1. Сначала JVM пытается выделить память через специфичный для текущего сборщика мусора интерфейс. Там происходит та же цепочка вызовов, что и была выше: сначала попытка аллоцировать из TLAB’а, потом попытка аллоцировать TLAB из кучи и создание объекта.
  2. В случае неудачи вызывается сборка мусора. Там же где-то замешана ошибка GC overhead limit exceeded, всевозможные нотификации о GC, логи и другие проверки, не имеющие отношения к аллокации.
  3. Если не помогла сборка мусора, то происходит попытка аллокации прямо в Old Generation (здесь поведение зависит от выбранного алгоритма GC), а в случае неудачи происходит еще одна сборка и попытка создания объекта, и, если не получилось и тут, то в конце концов кидается .
  4. Когда объект успешно создался, проверяется, не является ли он, часом, finalizable и если да, то происходит его регистрация, которая заключается в вызове метода (вас ведь тоже всегда интересовало, почему этот класс есть в стандартной библиотеке, но никогда никем не используется явно?). Сам метод явно написан очень давно: создается объект Finalizer и под глобальным (sic!) локом добавляется в связный список (с помощью которого объекты потом будут финализироваться и собираться). Это вполне себе оправдывает безусловный вызов в JVM и (частично) совет «не пользуйтесь методом finalize, даже если очень хочется».

В итоге мы теперь знаем про аллокации почти всё: объекты аллоцируются быстро, TLAB’ы заполняются быстро, объекты в некоторых случаях выделяются сразу в eden’е, а в некоторых идут через неспешные вызовы в JVM.

Инвестиции в IPO – как тут заработать

Относительно недавно, с развитием финансовой системы в интернете, инвестиции в IPO стали общедоступными. Конечно, у частных вкладчиков нет доступа к фондовым биржам, но участие в IPO доступно через брокеров. Их на сегодняшний день существует огромное количество, причем не только зарубежом, но и в странах СНГ. В одной из статей блога мы рассказываем об одном популярном брокере под названием United Traders, который предоставляет услуги доверительного управления средствами на рынке американских IPO. В чем же заключается суть инвестиций в IPO и как на них заработать? В первую очередь, нужно понимать, что вложение средств в IPO – это более рискованный вид инвестиций, чем приобретение акций известных компаний с многомиллиардной капитализацией. Но есть и существенный плюс, ведь IPO сможет принести гораздо большую прибыль, чем акции крупных компаний. Покупка акций IPO – это достаточно специфический вид вложений, и он имеет свои особенности:

  • Инвестируя через брокера в IPO, вы не сможете продать акции на протяжении определенного времени – это ограничение называют периодом Lock up. Как правило, он составляет 180 дней.
  • Порог входа при инвестиции в IPO достаточно высокий и может составлять несколько миллионов долларов. Инвестируя через брокера, вы можете входить мелкими суммами, так как все средства инвесторов собираются в общий пул.
  • Перед размещением своих акций компания публикует их примерную цену, но в реальности она может быть гораздо меньше. Как правило 60-70% компаний после размещений акций на IPO показывают более высокие результаты, тогда как около 30% не достигают обозначенной цены, из-за чего инвесторы терпят убытки.
  • Спрос на акции компании может повышаться и тогда заявки инвесторов могут исполняться не полностью. В такой ситуации, вкладывая 10 000$, инвестор может получить акций на 5 000$. До конца IPO точное количество купленных акций останется неизвестным.

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

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

Инвестиции в IPO – это одно из направлений моего заработка и в настоящий момент я инвестировал средства через брокера United Traders в две перспективные компании. Как видно со скринов ниже, обе уже принесли мне около 50% прибыли.

Примеры удачных IPO

Инвестиции в IPO компаний в 2019 году набирает особую популярность, так как многих инвесторов впечатляют успешные примеры недавно прошедших IPO. Среди тех компаний, которые набрали большие суммы инвестиций, есть и принесшие солидные проценты профита:

  • PagerDuty – компания, которая занимается разработкой программного обеспечения в сфере IT-безопасности, собрала 250$ млн. инвестиций, а цена ее акции после завершения IPO в 2019 году подорожала на 62%.
  • Zoom – провайдер видеосвязи, собрал на IPO 751$ млн., цена акций после завершения продажи поднялась на 67%.
  • Dropbox – IPO проходило в 2018 году, в первый же день акции подорожали на 36%.
  • Farfetch – акции онлайн-платформы для люксовых брендов подорожали на 42% в первый же день.
  • NIO – производитель электромашин, через два дня после размещения акций цена на них подорожала на 85%.
  • Xiaomi – компания разместила акции во втором квартале 2018 года, после чего они подорожали на 68%.
  • CarGurus – аналог auto.ru родом из США. Акции компании подорожали на 98%.

Календарь IPO

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

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

Что делать-то?

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

Используя всю ту же гипотезу о равномерности выделения памяти потоками, получаем простое уравнение: .Если мы готовы пожертвовать 10% eden’а, у нас 50 потоков, а eden занимает 500 мегабайт, то в начале сборки мусора 50 мегабайт может быть свободно в полупустых TLAB’ах, то есть в нашем примере размер TLAB’а будет 2 мегабайта.

В таком подходе есть серьезное упущение: используется предположение, что все потоки аллоцируют одинаково, что почти всегда неправда. Подгонять число к скорости аллокации самых интенсивных потоков нежелательно, обижать их менее быстрых коллег (например, scheduled-воркеров) тоже не хочется. Более того, в типичном приложении существуют сотни потоков (например в тредпулах вашего любимого app-сервера), а создавать новые объекты без серьезной нагрузки будут лишь несколько, это тоже нужно как-то учесть. А если вспомнить вопрос «Что делать, если нужно выделить 10% от размера TLAB’а, а свободно только 9%?», то становится совсем неочевидно.

Деталей становится слишком много, чтоб просто их угадать или подсмотреть в каком-нибудь блоге, поэтому пришло время выяснить, как же все устроено на самом деле: заглянем в исходники хотспота.Я пользовался мастером jdk9, вот CMakeLists.txt, с которым CLion начинает работать, если захотите повторить путешествие.

Все об аллокации расходов компании. Выпуск №3 ‘Разрабатываем методологию’

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

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

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

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

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

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

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

Оставшиеся «нераспределенными» после выполнения п.п.1 – 4 статьи расходов, подразделения и их
комбинации рассматриваются отдельно
Для этих блоков расходов может быть принято одно из следующих решений:

Исключение из периметра аллокаций
Распределение «равными долями» на все релевантные объекты аллокаций
Распределение пропорционально ранее распределенным суммам расходов (на шагах
1 — 4) на все релевантные объекты аллокаций
Распределение на все релевантные объекты аллокаций пропорционально их доходу
Распределение на все релевантные объекты аллокаций пропорционально уже сформированному на них финансовому результату
В дополнение хотел бы цитатой одного из коллег предостеречь от использования излишне сложных драйверов, необоснованно повышающих трудозатраты расчета и поддержания модели:
«Аллокация затрат на уборку помещений в зависимости от загрязненности рабочих мест – это, конечно, круто, но полезно только для анализа эффективности уборки, а не стоимости использования
убираемых помещений».

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

Пара слов о трении.

Что такое трение? В физике – сила трения – это сила, возникающая при соприкосновении двух тел и мешающая их взаимному движению. В финансах – это почти то же самое – трение это потери инвестора на применение его стратегии. К трению можно отнести: комиссии брокера на совершение операций на рынке, комисси управляющего менеджера, фонда или ETF, оплата книг для обучения или оплата сервисов.

Все эти суммы, сколь незначительными они бы не были – съедают часть вашей прибыли. Например комиссия обычного активного хедж-фонда составляет 2% от активов + 20% от прибыли выше бенчмарка.

То есть, например, если вы инвестируете $100000 долларов и фонд показывает доходность 10% при бенчмарке 8%, то в конце года вы платите $2000 плюс 20% от 2000$ (2% превосходства над бенчмарком), что равно еще $400, итого $2400. Учитывая что ваш доход составил изначально $10000, от него вы вычитаете $2400 потраченные на трение и получаете что чистый доход составил $7600, то есть по сути 7,6% при бенчмарке 8%.

Задача любого инвестора – свести трение к минимуму. Пассивное инвестирование считается одним из наиболее эффективных, с точки зрения трения, способов инвестировать, потому что вы платите только за операции по покупке инструментов, ребалансировку раз в год и комиссии ETF, что в сумме, конечно, значительно меньше, чем гарантированные 2% инвест-фонда. Поэтому грамотный инвестор всегда держит в уме свои расходы “на ведение бизнеса”.

Что там в Java 9?

В Java 9 всё почти так же. Можно проделать все те же действия, но с несколькими оговорками:

  • в параметры компилятора надо добавить (где sample — это имя вашего модуля);
  • в параметры запуска надо добавить:
  • в зависимости модуля надо добавить ;
  • у конструктора поменялась сигнатура, надо учесть.

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

Ещё исправили странную багу с : теперь на его месте , который там и должен быть. Мелочь, но приятно.

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

Зачем это нужно

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

С Equational reasoning всегда просто понять, что происходит: вы можете заменить результат на функцию и всё. Вам не нужно думать, в каком порядке функции вычисляются, не надо переживать насчёт того как оно поведет если поменять пару строчек местами, программа просто передает результаты одних функций в другие.

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

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

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

Соответственно если раньше с точки зрения компилятора оно выглядело так:

То после рефакторинга получилось следующее:

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

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

В общем и целом, ФП направлено на то, чтобы можно было судить о поведении функции наблюдая только её одну. Если вы, как и я, пишете на каком-нибудь C# в обычном императивном стиле, вам кроме этого нужно понимать, как у вас DI работает, что конкретно делает функция или , можно ли эту функцию безопасно из разных потоков вызывать или нет. В ФП вы смотрите на одну функцию, смотрите на её данные, и этой информации вам достаточно чтобы полностью понимать как она работает.

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

Телефонная связь Аллокация капитальных затрат

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

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

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

Плюсы для компании

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

Компания, разумеется, от этого только выигрывает.

Но как сотрудники относятся к таким идеям и насколько они готовы к переменам в своей жизни?

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

  1. Заработная плата. Большинство специалистов более охотно соглашаются при условии повышения уровня заработной платы.
  2. Новое место работы. Охотнее соглашаются на релокацию работники, которые направляются из мелких в крупные города либо в подразделение организации, находящееся за рубежом.
  3. Движение по карьерной лестнице. Релокация часто подразумевает карьерный рост специалиста, который переезжает в другой филиал на более высокую должность. Тогда у него больше шансов при временном перемещении вернуться обратно на аналогичную должность.
  4. Обустройство семьи. Молодые амбициозные специалисты, не обремененные семейными узами, обычно легче соглашаются на релокацию. Однако, в компании могут быть эффективные, надежные и грамотные сотрудники, имеющие семьи с детьми. Тогда работодателю придется решать для них жилищный вопрос, проблемы переезда и обустройства детей в учреждениях по новому месту жительства. Нередки случаи, когда организация для них арендует за свой счет жилье на время контракта или предоставляет беспроцентную рассрочку на его приобретение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector