en
Feedback
Javanese Online

Javanese Online

Open in Telegram

Статьи и новости, наблюдения и советы. Кодревью: http://javanese.online/%D1%80%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_%D0%BA%D0%BE%D0%B4%D0%B0/ Обсуждение в @javanese_questions Материалы пишет @Harmonizr

Show more
723
Subscribers
No data24 hours
+37 days
+530 days
Posts Archive
Финансовая математика для IT-инженеров - Сколько нужно денег, чтобы жить на проценты? - Как устроены опционы? - Как ускорить
Финансовая математика для IT-инженеров - Сколько нужно денег, чтобы жить на проценты? - Как устроены опционы? - Как ускорить расчёт доходности облигации в 1000 раз одной строкой кода? IT-инженеры сталкиваются с вопросами из финансовой математики по-разному: из любопытства, при управлении личными финансами, по работе. Многие интересные темы сложно найти за пределами академических источников. Мы считаем это не вполне справедливым. Так появился наш проект. Мы сделали сайт, где собираем материалы, которые доступно рассказывают о нашем увлечении — финансовой математике. В нынешней подборке: видео-лекции, статьи. Скоро: задачи, тесты на проверку знаний по финансовой математике, митапы. Заходите на сайт, смотрите подборку видео и статей. Если знаете полезные материалы по теме, которых пока нет на сайте — предлагайте! Самые интересные обязательно опубликуем. Надеемся, вместе мы сможем сделать финансовую математику чуть более доступной для IT-инженеров https://finmath4it.ru/

Пара слов о гонках в обзёрваблах Property в @kotlin_lychee — это аналог Property в JavaFX или BehaviorSubject в RxJava: можно читать значение, подписываться на изменения и отписываться от них, а в MutableValue можно присваивать новое значение. В принципе понятно, какие гонки бывают в многопоточном окружении, поэтому расскажу только об однопоточных гонках. Когда значение проперти меняется, об этом должны узнать все подписчики. А значит, проперти в цикле вызывает коллбэки с чужеродным кодом. Который вполне может: • присвоить проперти новое значение. Тут примитивная реализация уйдёт в рекурсию, разнесёт всем новое значение, а потом вернётся по стеку и продолжит разносить старое значение. В Lychee же проперти хоть и сразу меняет значение, но уведомляет строго в порядке очереди; • отписаться. Примитивная реализация может хранить подписчиков в COWArraySet, чтобы не вылетало ConcurrentModificationException, но этого мало: нельзя уведомлять отписавшихся, нужно удалять сразу; • добавлять новых подписчиков. У проперти всегда можно считать свежее значение, которое будет более актуальным, чем то, которое мы доставляем прямо сейчас. Поэтому подписчики ставятся в очередь и не получают несвежие значения. Тут нужно добавить, что проперти «холодные» и «ленивые». Например,
val nProp = propertyOf(0)
val facProp = nProp.map(::factorial)
repeat(100500) { nProp.value = it }
Функция factorial вызовется ноль раз, ведь никто не подписан на facProp и не запрашивал значение. То есть проперти всегда знает, смотрят ли на него или можно расслабиться. Теперь к делу. Я запилил LazyView — эдакий ViewStub для вёрстки из кода:
addView(
  lazyView(visibleProp) {
    mySuperHeavyView()
  }
)
Дальше происходит следующее: • пользователь, нажимая кнопку, присваивает true в какое-то проперти; • visibleProp зависит от него через серию всяких map и тоже становится true (а мы прямо сейчас уведомляем подписчиков об изменении); • LazyView выпиливается из контейнера, отписывается от visibleProp, создаёт superHeavyView и подписывает его на ту же visibleProp; * кнопка отваливается, все последующие клики бесполезны. Правда, можно отправить экран в бэкстек и вернуться на него, тогда всё оживёт. И что это было?! 1. Я ошибся, когда разрабатывал механизм уведомления, решив, что если мы сейчас уведомляем, значит, на нас хоть кто-то подписан. Звучит логично, но нет: можно же отписаться прямо в процессе уведомления. А потом подписать кого-нибудь ещё. Состояние «на меня смотрят» всё же может меняться. 2. Исправил, завалил другой тест: в одной из реализаций проперти я позабыл, что подписчики бывают не только «нормальные», но и ждущие в очереди. Поэтому, если кто-то отписывается, но отсутствует в списке «нормальных», нужно проверить ещё и очередь. Коммит для любителей пожёстче · Релиз · Тред в Твиттере на английском

В докладе есть пример, где я рисую заголовок с помощью ItemDecoration. Удобно, что не нужно добавлять вьютайпы. Хорошо, что такой текст не требует текствьюшки и рисуется очень быстро. Но я забыл озвучить один нюанс: accessibility. Экранные дикторы не видят этого текста. Поэтому делать заголовки декораторами я всё-таки не рекомендую.

Аргументы фрагмента Заезженная тема, но общепринятого варианта, кажется, не существует. Как это делаю я: * прячу дефолтный ко
Аргументы фрагмента Заезженная тема, но общепринятого варианта, кажется, не существует. Как это делаю я: * прячу дефолтный конструктор, чтобы он был доступен только рефлекшену; * делаю конструктор (не фабрику!) с параметрами, который сохраняет аргументы; * делаю геттеры (не by lazy!) аргументов.

Speaker's Deck рукожопит, поэтому так.

Начинаем начинать!

Друзья, привет! Android Academy SPb запускает онлайн-курс Android Advanced. И наша первая тема — Views & Graphics! Меня зовут Михаил Горюнов @Harmonizr, я Android-разработчик-фрилансер. И 22 октября я подробно расскажу, как в Android работают View. На примерах покажу, как писать свои и вьюхи и ViewGroup, Drawable и ItemDecoration. Также поговорим про работу Canvas, Paint и Shaders. Лекция будет полезна как начинающим, так и опытным разработчикам. Не пропустите! 😉 Регистрация

Готовлю доклад про графику для продвинутого курса Android Academy.
Готовлю доклад про графику для продвинутого курса Android Academy.

Вы когда-нибудь разрабатывали Telegram-ботов?
Anonymous voting

Менеджер зависимостей для Android Меня вдохновляет Graviton Browser — браузер JVM-приложений. В качестве адреса ему можно передать groupid:artifactId — гравитон скачает последнюю версию вместе со всем деревом зависимостей и запустит Main Class. Подобное можно провернуть для андродиа, но немного в другой форме: — на телефон устанавливается приложение-менеджер. Графического интерфейса у него нет; — берётся любое приложение, из него выпиливаются библиотеки, вместо них нужно взять одну маленькую — коннектор к менеджеру зависимостей; — в метадату манифеста вписываются зависимости, чтобы менеджер пакетов их увидел; — на старте приложение связывается с менеджером пакетов и получает от него необходимые dex'ы. Это решает сразу несколько проблем: — раздутый размер APK. Все библиотеки теперь находятся снаружи, популярные библиотеки не дублируются в каждом приложении; — фиксы библиотек можно доставлять без пересборки и перезаливки (как, впрочем, и баги); — менеджер пакетов учитывает версию Android и может подхватывать нужные пакеты в зависимости от этого. Например, брать Гришкин liteX для SDK21+ или, наоборот, подключать бэкпорт CompletableFuture, Streams, java.time, если платформа старая. Есть, конечно, и минусы: — не все соблюдают semVer, можно по неосторожности доставить ломающие изменения; — правила Маркета не позволяют подгружать код не из Маркета; — возможны просадки времени старта. Есть вам нравится эта #идея и вы решите поучаствовать в реализации, стучите в личку — помогу чем смогу.

ReadWriteLock простыми словами ReadWriteLock — как кастрюля: * можно варить только один суп в один момент времени; * нельзя подъедать суп, пока он варится (ой!); * когда суп готов, его можно есть несколькими ложками.

Дайте два! void bulk(Iterable<? extends T> ts) void bulk(Stream<? extends T> ts) Так как StreamEx реализует и Stream, и Iterable, для выражения bulk(streamEx) javac не сможет выбрать нужную перегрузку: оба варианта одинаково хороши. Какое решение вы бы выбрали?

Сегодня вышел ProGuard 7, с чем и поздравляю разработчиков десктопных приложений. Кстати, проект наконец-то перебрался в гитхаб.

Многие знают jlink — инструмент, который собирает уменьшенную JVM, чтобы её удобно было поставлять пользователям (актуально для десктопных приложений). Но jlink нормально работает только с модульными проектами, а на jigsaw все забили. Оказывается, есть аналогичная штука для немодульных проектов.

Итератор стоит между элементами. next() перепрыгивает через элемент и возвращает его:
| 0 1 2
.next() => 0
0 | 1 2
.next() => 1
0 1 | 2
.previous() => 1 (sic!)
0 | 1 2

ResultSet и Cursor стоят на строках и переходят с одной строки на другую:
[] 0 1 2
.next() или first()
[0] 1 2
.next()
0 [1] 2
.previous()
[0] 1 2

«“Велосипед” — это просто вредная риторическая уловка, чтобы оправдать свою лень или самоутвердиться в споре» Часто встречаю пару заблуждений, которые в утрированной и доведённой до абсурда формулировке звучат так: • нельзя использовать малоизвестные инструменты. У библиотеки должны быть десятки тысяч звёзд на гитхабе и выделенная какой-нибудь корпорацией команда для поддержки; • нельзя делать свои инструменты, когда в мире уже есть хоть что-нибудь отдалённо похожее. Статья @fillpackart развеивает эти заблуждения.