Ru
ГлавнаяКаналыТехнологии → По-явански

По-явански 🕘 история названий (1)

@javanese_online · Технологии

Новости, статьи, кодревью; наблюдения и советы. Кодревью: 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

817подписчиков сейчас
110.0%ERR
0.0цитируемость
3постов/день
Русскийязык
Россиягео
Подписаться в Telegram
Данные обновлены 21.07.2020

Публикации всего: 52

Постов на странице: 10 30 50 Страница 1 из 6
Корень корня всех зол Потрясающая археологическая работа по поиску истоков известнейшей фразы о преждевременной оптимизаци. Tl;dr заявление о том, что 97% кода можно не оптимизировать, но нужно знать, какие именно 3% кода «горячие», строится на анализе существовавших на момент написания статьи программ, которые по современным меркам считались бы очень простыми и маленькими. Зачастую там действительно был один основной цикл, а производительность всего остального не имела значения.
❤ 2 Перейти к публикации →
Selector expression На стыке функций-расширений и функционального типа есть такой замечательный конструктор типа: T.() -> R. Выражения таких типов спокойно кастятся к (T) -> R и обратно, а func(args) привычно раскрывается в func.invoke(args). Но у варианта-расширения есть и особый синтаксис: receiver.func(args). Он логичный, понятный и консистентен с написанием типа и синтаксисом вызова расширений.
val b = String::isBlank
"".b()
А ещё он открывает нам знатный инсайд: между receiver. и (args) может находиться не только идентификатор, но и переменная, вернее, выражение! Для начала — несколько бесполезных способов записать "".isBlank(): • "".(String::isBlank)() — function reference • "".(fun String.() = isBlank())() — анонимная функция • "".({ s: String -> s.isBlank() } as String.() -> Boolean)() — лямбда • "".(providePredicate())() — произвольный вызов, возвращающий функцию Уверен, что это побочка, вызванная там, как устроен синтаксис expr.variable(). Тем не менее, в следующем примере:
value
    .validate()
    .let {
        val t =
            if (simple) transform
            else provideComplicatedTransform()
        it.t(args)
    }
    .serialize()
можно избавиться от let с лишней переменной:
value
    .validate()
    .(
        if (simple) transform
        else provideComplicatedTransform()
    )(args)
    .serialize()
что читается более последовательно и выглядит менее мусорно.
👍 6 🤯 6 👏 1 Перейти к публикации →
Что значит «no-cache», хвостовики, 1xx коды состояния, опечатки и прочие необычности в привычном HTTP. В статье с просторов интернета: HTTPWTF. Необычное в обычном протоколе.
👍 3 ❤ 1 Перейти к публикации →
Что в сигнатуре тебе моей? Есть в kotlin-stdlib функция text.ifEmpty { default }. Реализована она крайне просто: if (isEmpty()) defaultValue() else this. Интересна же функция тем, как она обходится с типами:
"".ifEmpty { "" } // String
"".ifEmpty { null } // String?
stringBuilder.ifEmpty { "" } // CharSequence & …
"".ifEmpty { 1 } // Comparable<*> & Serializable
Такой вывод типов следует из сигнатуры. Давайте разберём поэтапно, в чём там волшебство. Например, если бы сигнатура была String.ifEmpty(() -> String): String то такое использование было бы невозможно: stringBuilder.ifEmpty { null } ❗️ ресивер должен быть строкой, а не билдером, ❗️ лямбда должна возвращать строку, а не null. То есть к функции можно сформулировать такие требования: 🔹 тип ресивера должен быть как можно шире. Функция isEmpty() объявлена у CharSequence — он-то нам и нужен, 🔹 тип дефолта должен быть ещё шире: там хоть null, хоть попугаи, хоть козявки — мы с ними никак не взаимодействуем, 🔹 возвращаемый тип должен сужаться по типам параметров: если там нет нуллов — их не должно быть на выходе и так далее. Пусть будет такая сигнатура: fun <C : CharSequence, T, R> C.ifEmpty(() -> T): R. Что будем писать в where? Объединений и пересечений в Котлине нет, то есть на месте R нельзя написать ни C & T, ни C | T. Интуитивно хочется написать R : C, R : T. Но это неверно: тут написано «возврат у́же, чем ресивер, и у́же, чем дефолт». У нас же требование противоположное: C и T должны «пролезть» на выход, через R. Правильное напрваление — C : R, T : R. Правда, компилятор корёжит, что C и так : CharSequence, куда тут ещё баунд. Настоящая сигнатура:
@kotlin.internal.InlineOnly
public inline fun <C, R> C.ifEmpty(
    defaultValue: () -> R,
): R where C : CharSequence, C : R {
Ошибку компиляции здесь затыкает приватная аннотация InlineOnly. Нам так делать нельзя, зато можно @Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER"). Обсуждение синтаксиса, который позволял бы писать подобные сигнатуры без изврата: KT-209
🔥 5 ❤ 2 👍 2 · всего 10 Перейти к публикации →
— Добро пожаловать на курс экстремистского программирования! — Может, экстремального? — Может...
🌚 7 👍 2 Перейти к публикации →
Двуязычный API Положим, есть функция на Kotlin: fun <R> exec(f: () -> R): R её, конечно, можно использовать из Java: exec(() -> { return Unit.INSTANCE; }); но выглядит это убого. Для создания более дружелюбного интерфейса можно сделать следующее: 1. добавить перегрузку с «родным» для Java функциональным интерфейсом fun <R> exec(f: Supplier<R>): R 2. добавить частный случай для R = Unit fun exec(f: Runnable) 3. спрятать ЪКотлинЪ-вариант от Джавы @JvmSynthetic fun … либо сделать его менее заметным @JvmName("exec_4k") fun … 4. сделать ЪДжаваЪ-вариант менее заметным в Котлине @JvmName("exec") fun exec_4j(… Итого:
@JvmName("exec_4k")
fun <R> exec(f: () -> R): R = f()

@JvmName("exec")
fun <R> exec_4j(f: Supplier<R>): R = f.get()

@JvmName("exec")
fun exec_4j(f: Runnable) = f.run()
🌚 8 👏 2 Перейти к публикации →
🔌 Поддержка K2 готова, а вместе с ней • улучшен фикс в инспекции по ловле регекспов [а-яА-Я] • жалуюсь на "#ЦЦВВЕЕТТ".toColorInt() так же, как на Color.parseColor • блюду порядок сортировки атрибутов стиля при вызове context.withStyledAttributes так же, как и для context.obtainStyledSttributes В целом получился чисто технический релиз, основная фишка лишь в том, что теперь плагин работает 😌
🔥 3 ❤ 2 Перейти к публикации →
Роберт Лафоре. Структуры данных и алгоритмы Java, второе издание Чувствуется, что Java — не родной, не любимый язык автора: кодстайл не соблюдается, классы и файлы порой называются со строчной буквы. Имена методов часто не передают их сути. Первый же пример кода (с. 32) не скомпилируется. Скоупы переменных чересчур широкие. Положение фигурных скобок выбрано рандомом (попробуй разбери вложенность на с. 167). Вместо стандартного toString (EJ3*, Item 12) у многих классов есть функция, которая печатает содержимое в stdout. Наличие псевдополя length у массивов игнорируется, хотя во введении в Джаву автор объяснял про него. Модификатор final не используется. int[] после создания вручную заполняется нулями. Ну и так далее — короче, с языком полный провал. С момента выхода оригинала (2003, SAMS, времена Java 1.4) до перевода в моих руках (2019, Питер, Java 11) прошла целая эпоха. Было очень наивными решением издавать книгу без изменений. Например, для демонстрации материала автор написал несколько апплетов — олды здесь? Непосвещённый читатель задолбается их запускать. Также автор по какой-то причине упоминает классы Stack, Vector и Hashtable. Хоть дженерики пока не появились, но привычные нам коллекции тогда уже завезли. Работа с массивами. Понимаю, что пример, где делают всё ручками, быть должен — это закон жанра. Но как насчёт использования методов indexOf*, System.arraycopy, Arrays.binarySearch в дальнейшем? Без них в реальном мире жить неуютно, как и говорить о сортировке, не упоминая компараторов. Везде, где автор использует массивы, нет примеров ресайза — а неискушённый читатель может и не знать про Arrays.copyOf. Не понятно, что автору мешало в своих коллекциях сделать инициализацию готовым массивом. Десять строчек с arr.insert() — это ж боль. Кстати, видите утечку памяти на с. 77? А она есть! См. EJ3*, Item 29, первый листинг. Дэку уделён один абзац — мол, такая штука есть, но не очень нужна. На самом деле ArrayDeque (кольцевой буфер) — это самая универсальная коллекция во всём Котлине: она тебе и вектор, и обе очереди. О хорошем. В книге доходчиво объясняется асимптотика, вплоть до изображений графиков и разъяснения, что такое логарифм — если кто не знал, а потом забыл. Алгоритмы сортировки хорошо объясняются на словах и вдобавок визуализируются. Деревья и графы визуализируются — а это очень важно для понимания темы. Двоичные деревья (поиска и пирамида a.k.a. куча), красно-чёрные, В-деревья — это всё очень интересно и увлекательно (хотя к-ч я так до конца и не понял). Есть перевод математических выражений в префиксную нотацию, есть префиксное дерево. Можно было бы и про AST немного поговорить :) Связанный список. Автор утверждает, что эта структура данных, в отличие от вектора, использует память эффективно, ведь пустой хвост массива отсутствует. Посчитаем? Полупустой массив занимает 2n памяти. Узлы же, в каждом из которых есть ссылка на данные, следующий узел, невидимая ссылка на класс и пэддиннг, занимает 4n. Частота и сложность аллокаций, локальность — тут только свернуться клубочком и плакать. Ещё один момент из реальной жизни забыт: проверки корректности входных данных. Книжный стек считает, что пользователь сам проверит, не пустой ли он. Наивно! (EJ3*, Item 49) В рекомендациях по выбору структуры данных делается нелепое допущение: проще — лучше, ведь тебе придётся реализовывать алгоритм самому! Доходит до того, что вектор при малом объёме данных стоит предпочесть хэш-таблице. На деле же критерий выбора звучит так: нужен порядок вставки или доступ по ключу? Вердикт: интересная книга. Читать только под присмотром взрослых. *EJ3 — Joshua Bloch. Effective Java, Third Edition *Arrays.indexOf не существует. Его надо написать один раз либо использовать методы из ArraysKt
👍 8 ❤ 5 👏 2 Перейти к публикации →
Довольно интересная книга, и, как видно по закладкам, вызывающая у меня обилие разнообразных реакций. Близко к сердцу пришлась мысль, что большое — хрупко: оно сложное, внесение изменений аукается неожиданными последствиями, а внезапные встряски могут всё…
👍 13 Перейти к публикации →
Антихрупкость – Нассим Талеб
❤ 6 Перейти к публикации →
1 2 3 5 6

История названий канала

14.08.2026 название Javanese Online По-явански
Дата — момент, когда изменение заметил наш обход.

Другие каналы категории