ru
Feedback
Javanese Online

Javanese Online

Открыть в 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

Больше
723
Подписчики
Нет данных24 часа
+37 дней
+530 дней

Загрузка данных...

Облако тегов
Нет данных
Возникли проблемы? Пожалуйста, обновите страницу или обратитесь к нашему support-менеджеру .
Входящие и исходящие упоминания
---
---
---
---
---
---
Привлечение подписчиков
декабрь '24
декабрь '24
+5
в 0 каналах
ноябрь '24
+21
в 0 каналах
Get PRO
октябрь '24
+34
в 0 каналах
Get PRO
сентябрь '24
+7
в 0 каналах
Get PRO
август '24
+11
в 0 каналах
Get PRO
июль '24
+12
в 0 каналах
Get PRO
июнь '24
+4
в 0 каналах
Get PRO
май '24
+28
в 0 каналах
Get PRO
апрель '240
в 0 каналах
Get PRO
март '24
+58
в 0 каналах
Get PRO
февраль '240
в 1 каналах
Get PRO
январь '240
в 0 каналах
Get PRO
декабрь '230
в 0 каналах
Get PRO
ноябрь '23
+7
в 0 каналах
Get PRO
октябрь '23
+28
в 1 каналах
Get PRO
сентябрь '23
+38
в 0 каналах
Get PRO
август '23
+40
в 0 каналах
Get PRO
июль '23
+29
в 0 каналах
Get PRO
июнь '23
+20
в 0 каналах
Get PRO
май '23
+37
в 0 каналах
Get PRO
апрель '23
+27
в 0 каналах
Get PRO
март '23
+26
в 0 каналах
Get PRO
февраль '23
+18
в 0 каналах
Get PRO
январь '23
+19
в 0 каналах
Get PRO
декабрь '22
+9
в 0 каналах
Get PRO
ноябрь '22
+10
в 0 каналах
Get PRO
октябрь '22
+12
в 0 каналах
Get PRO
сентябрь '22
+16
в 0 каналах
Get PRO
август '22
+14
в 0 каналах
Get PRO
июль '22
+15
в 0 каналах
Get PRO
июнь '22
+7
в 0 каналах
Get PRO
май '22
+27
в 0 каналах
Get PRO
апрель '22
+12
в 0 каналах
Get PRO
март '22
+8
в 0 каналах
Get PRO
февраль '22
+43
в 0 каналах
Get PRO
январь '22
+17
в 0 каналах
Get PRO
декабрь '21
+12
в 0 каналах
Get PRO
ноябрь '21
+17
в 0 каналах
Get PRO
октябрь '21
+23
в 0 каналах
Get PRO
сентябрь '21
+20
в 0 каналах
Get PRO
август '21
+10
в 0 каналах
Get PRO
июль '21
+22
в 0 каналах
Get PRO
июнь '21
+10
в 0 каналах
Get PRO
май '21
+6
в 0 каналах
Get PRO
апрель '21
+23
в 0 каналах
Get PRO
март '21
+33
в 0 каналах
Get PRO
февраль '21
+62
в 0 каналах
Get PRO
январь '21
+10
в 0 каналах
Get PRO
декабрь '20
+391
в 0 каналах
Дата
Привлечение подписчиков
Упоминания
Каналы
21 декабря0
20 декабря0
19 декабря0
18 декабря0
17 декабря+2
16 декабря+1
15 декабря0
14 декабря0
13 декабря0
12 декабря0
11 декабря0
10 декабря+1
09 декабря0
08 декабря0
07 декабря0
06 декабря0
05 декабря+1
04 декабря0
03 декабря0
02 декабря0
01 декабря0
Посты канала
Раздельная компиляция, min, compile, target В целом Java-технологии привычные к раздельной компиляции. Серверные приложения компилируются с Java Class Library, которая подкладывается в compile classpath при сборке, а запускаются с другим экземпляром JCL, которая лежит на сервере. Однако, эта раздельность почти не чувствуется. Она незримо присутствует и заключается в том, что в итоговом jar у нас не лежит весь java.lang, java.util и что мы там ещё любим. Мы запускаем приложение с той же версией JDK, с которой собирали, и всё просто работает. Таким образом, приложение разрабатывается под одну версию платформы, без оглядки на более старые и с надеждой на совместимость с новыми. В desktop-приложениях (кто-то их ещё пишет?) всё ещё проще: зачастую JVM приносят с собой, и раздельной компиляции как не бывало. В Android же, как известно, зоопарк: на конечных устройствах много разных версий. И вот тут система сборки спроектирована очень удачно: • compile SDK — последняя версия, известная разработчику приложения на момент сборки. Она подкладывается в compile classpath, за счёт чего разработчик видит все новые фичи платформы; • min SDK — минимальная поддерживаемая версия. Старой платформе, которую разработчик не хочет поддерживать, позволяет отклонять установку приложений. Инструментарию позволяет подсказать программисту, что те или иные declarations недоступны в min и могут отсутствовать в runtime classpath, поэтому нужно обернуть их использование в if; • target SDK — версия, на поведение которой рассчитывает приложение. Позволяет более новой версии платформы сохранить поведение старой в старом приложении. Таким образом, в быстро меняющемся мире Android-приложение компилируется для свежей версии платформы (compile SDK), ифами поддерживает более старые версии (вплоть до min SDK), а платформа, если она новее, чем ожидаемая (target SDK), сохраняет старое совместимое поведение (тоже ифами). Это прекрасно. Это шедевр. Для сравнения, ситуация в мире плагинов для IntelliJ: выбираешь одну версию, которая и будет твоим compile и min. Хочешь поддержать постарше — опускаешь версию, перестаёшь видеть новые declarations. Если в новых версиях что-то deprecated — ты об этом узнаешь на этапе валидации плагина, где-то после компиляции и упаковки. Именно поэтому при обновлении IDE плагины часто либо отключаются (разработчик указал максимальную поддерживаемую версию), либо разваливаются (мой вариант:). Зависишь от других плагинов? Вообще страдай. Там может быть установлена любая версия. Например, если зависишь от Android-плагина для IDE, то при компиляции видишь версию, которой полгода, а в бетах Android Studio уже много раз переименовали классы, поменяли на интерфейсы, переместили в другой пакет. (И сделали это в стенах той же компании, где придумали min, compile, target.) Удачи!

2
Раздельная компиляция, min, compile, target В целом Java-технологии привычные к раздельной компиляции. Серверные приложения компилируются с Java Class Library которая подкладывается в compile classpath при сборке, а запускаются с другим экземпляром JCL, которая лежит на сервере. Однако, эта раздельность почти не чувствуется. Она незримо присутствует и заключается в том, что в итоговом jar у нас не лежит весь java.lang, java.util и что мы там ещё любим. Мы запускаем приложение с той же версией JDK, с которой собирали, и всё просто работает. В desktop-приложениях (кто-то их ещё пишет?) всё ещё проще — зачастую JVM приносят с собой, и раздельной компиляции как не бывало. В Android же, как известно, зоопарк: на конечных устройствах много разных версий. И вот тут система сборки спроектирована очень удачно: • compile SDK — последняя версия, известная разработчику приложения на момент сборки. Она подкладывается в compile classpath, за счёт чего разработчик видит все новые фичи платформы.
1
3
Размножение массивов String::repeat — произведение искусства. Arrays.fill же написан банально и буднично, но я подозреваю, что он успешно векторизуется.
1 919
4
Пару слов про зерокодинг и ни одной шутки про зерозарплатинг Да, из готовых компонентов можно собрать сайт, приложение или круд. Оно даже будет работать. Я смотрю на это просто как на программирование на более высоком уровне. Что здесь примечательно для нас, разработчиков? А то, что компоненты «среднего» уровня написаны такими же программистами. И если менеджер мышкой натыкивает приложение быстрее, чем профессиональный разработчик, то у нас, коллеги, наблюдается проблема с job security качеством и доступностью компонентов. Если OAuth из конструктора интегрируется быстрее и работает лучше, чем решение с гитхаба, значит, мы залайкали не тот репозиторий, автор его недодокументировал или вообще бросил на полпути. Если нам данные приходят по одной схеме, и мы, чтобы трансформировать их в другую, удобную нам, выражаем обе через ДТОшки и пишем маппер между ними, значит, библиотека, которой мы намазываем данные на классы, не решает нашу задачу. Если прокладка для работы с БД заставляет нас… ну и так далее. Зерокодинг никогда не станет мощнее и гибче, чем «настоящее» программирование. А наша задача — делать так, чтобы последнее не отставало по скорости и качеству. Хочу надеяться, что конкуренция со стороны зерокодинга поспособствует повышению качества нашего родного программирования.
1 802
5
Один мой коллега постоянно забывал, как кого зовут, из-за чего в нашем лексиконе появились два собирательных персонажа — Кирилл Гладков и Алексей Розов. Дошутились таки!
871
6
Если вы когда-нибудь искали способ поставить бряку для одного конкретного экземпляра, то… вот он!
Если вы когда-нибудь искали способ поставить бряку для одного конкретного экземпляра, то… вот он!
519
7
Привет, я подсяду? Поговорим о корпоративной коррупции? Давайте разберёмся, как в опенсорс попадают всякие технологии. Вот мне кусочек рационального мышления подсказывает, что компания решает свои задачи, свои проблемы, выпускает что-то для себя, внедряет технологию в свои процессы, извлекает из этого коммерческую выгоду, и — почему бы нет — делится с другими, собирая багрепорты от широкой аудитории и повышая качество — а это снова выгода. Ну, логично, мне кажется. Вроде как-то так должно работать. Теперь давайте прикола ради глянем библиотеку, которая не работает: она должна помогать следить за внешним видом приложения, но даже стандартную кнопочку со стандартным stateListAnimator'ом в дефолтной теме скриншотит неправильно, не говоря уже про скруглённые аватарки, которые у них в собственном приложении таки есть, судя по нагугленным скриншотам. Чистая прибыль в 23 гигабакса даёт о себе знать, нужно срочно стартовать новый проект, обосновать его целесообразность, выбить финансирование. Написанный код потом можно выкинуть — не прижился. Ах да. PixelCopy.request. Шах и мат, аферисты.
471
8
ой
ой
472
9
Редактируемый список — EditText внутри RecyclerView Очень много лулзов на StackOverflow по этому вопросу. Написать адаптер с эдиттекстами под силу каждому, а вот получить назад отредактированные данные могут не только лишь все. Рассмотрим для начала очевидно нерабочий способ: for-each по вьюшечкам. Как ни странно, я видел такое решение в продакшене. Чтобы оно работало, ресайклер был завёрнут в скроллвью! Следующий сомнительный вариант: нацепить TextWatcher и записывать результат Editable.toString() на каждый тык пользователя по клавиатуре. Название Editable, кстати, намекает нам на мутабельность редактируемого буфера. Так возникает ещё одна стратегия — дёрнуть Editable getText(), а не слушать каждое изменение. Тогда байндинг будет выглядеть так: editText.setText(editables[position] ?: strings[position]) editables[position] = editText.text EditText создаст мутабельную копию строки. А можно сделать это самостоятельно, потому что в editables уже может лежать нужный буфер. Только нужно отвадить EditText от копирования, заменив Editable.Factory. Итоговый gist и ответ на SO.
424
10
Недавно меня посетила красивая #идея — вот бы приложения карт умели показывать слои, предоставленные другими приложениями! Открываешь Organic, 2GIS или что там сейчас есть из картографии — а туда сразу подтягиваются такси, самокаты, каршеринг, общественный транспорт, парковки — в зависимости от того, какие провайдеры установлены. Философия UNIX во всей красе. Как и большинство других идей, я не первый, к кому они приходят. Например, есть вот такая закрытая/коммерческая интеграция. А хочется — публичный интерфейс для всех.
379
11
Интерфейсы коллекций Вчера задали мне этот вопрос на собесе. Ну я и перечисляю: Iterable, Collection, List, Set, SortedSet, NavigableSet, Queue, Deque; Map, ConcurrentMap — тут остановился в ожидании реакции собеседующего. Глазами хлопаю, мол, что, надо ещё? Оказывается, это почти всё. Для пущего эффекта можно выучить: BlockingQueue, TransferQueue, BlockingDeque; SortedMap, NavigableMap, ConcurrentNavigableMap.
364
12
Опаньки, оказывается, из типового параметра можно убрать нуллабельность (подсветка синтаксиса тоже удивлена). Источник
Опаньки, оказывается, из типового параметра можно убрать нуллабельность (подсветка синтаксиса тоже удивлена). Источник
460
13
🔴 Стартует собеседование в прямом эфире Проводит Михаил Горюнов @Harmonizr, разработчик Android-приложений, библиотек и инст
🔴 Стартует собеседование в прямом эфире Проводит Михаил Горюнов @Harmonizr, разработчик Android-приложений, библиотек и инструментов. Миша будет собеседовать на позицию Android разработчика без уровня (требования здесь) P.S. Запись останется на канале #AndroidBroadcast #собеседование
273
14
🔴 Стартует собеседование в прямом эфире Проводи Михаила Горюнова @Harmonizr, разработчик Android-приложений, библиотек и инс
🔴 Стартует собеседование в прямом эфире Проводи Михаила Горюнова @Harmonizr, разработчик Android-приложений, библиотек и инструментов. Миша будет собеседовать на позицию Android разработчика без уровня (требования здесь) P.S. Запись останется на канале #AndroidBroadcast #собеседование
14
15
Парсинг ботокоманд /add_thing Name Description /add_thing Name 'Long description' Как распарсить эти команды и не сойти с ума+1
Парсинг ботокоманд /add_thing Name Description /add_thing Name 'Long description' Как распарсить эти команды и не сойти с ума? Внутри JDK периодически используется StringTokenizer, но это просто String.split() образца 1995 года. А нужный класс, который понимает кавычки, называется StreamTokenizer, и, как следует из названия, он ещё и стрим разобрать может.
360
16
Сбор заявок на участие в собеседовании Мы ищем кандидата, кто пройдет в прямом эфире собеседование на вакансию, идентичную ре
Сбор заявок на участие в собеседовании Мы ищем кандидата, кто пройдет в прямом эфире собеседование на вакансию, идентичную реальной, в прямом эфире у Михаила Горюнова @Harmonizr , разработчика Android-приложений, библиотек и инструментов. Миша будет собеседовать на позицию Android разработчика (речь не идет про уровень или года опыт), а с требованиями можно ознакомиться здесь   @android_broadcast #собеседование
209
17
Transient Iterator Что может выстрелить в этом кусочке кода: map.entries.toSet()? А вот что: entrySet().iterator().next() возвращает себя — этот же итератор, который впридачу реализовывает Map.Entry. В итоге из энтрей непустой Map всегда получается Set из единственного Entry. С одной стороны, это жёсткая подстава. С другой — экономный способ просмотреть любое количество элементов за константную память. Поэтому в тех местах, где это может быть полезно, я предоставляю оба варианта — «нормальный» итератор и «мимолётный». Так же можно поступить с итератором по строкам файла: не возбраняется фильтровать, искать префиксы или какие-то символы, а потом уже выгружать в память необходимое подмножество элементов.
406
18
Стрельба по-македонски на Java
341
19
Эффективное ООП Files.readAllLines(path).size Страшно? Жутко? Жизнь — боль? Вывод: это ваше ООП неэффективно, объекты нинужны, они только память тратят. Нужна функция file_count_lines(path)! абстракция либо неверно выбрана, либо коряво реализована. Рассмотрим оба варианта. Другая абстракция: Iterator<CharSequence> & Closeable. Файл проматывается по мере доступа к элементам. CharSequence можно выгрузить в память методом toString(), до этого он просто помнит отступ и длину в файле, а charAt() заглядывает в mmap. Некорявая реализация: List<CharSequence> & Closeable. Написать такой лист сильно сложнее, чем итератор, но нет ничего невозможного: • size при первом вызове проматывает файл и строит индекс — складывает позиции всех \n в массив интов — и возвращает его размер, • get(at) проматывает файл до нужного места, достраивая по пути индекс, если он неполный. Естественно, оба метода используют один и тот же индекс и умеют достраивать его по мере необходимости. Гипотетический Files.listOfLines(path).forEach() пробегает итератором по файлу ровно один раз. Самый тяжёлый сценарий, Files.listOfLines(path).map(CharSequence::toString), приведёт к накладным расходам в виде промежуточных CharSequence и индекса, но это копейки.
447
20
Приняв во внимание обратную связь сообщества, редакция приняля решение прекратить ведение канала на неопределённый срок.
320