Как стать автором
Обновить
629
0
Тагир Валеев @tagir_valeev

Программист

Отправить сообщение

Что полезно знать Java-разработчику про вывод типов

Время на прочтение9 мин
Количество просмотров20K

image


В Java 8 кардинально переработали процедуру вывода типов выражений. В спецификации появилась целая новая глава на эту тему. Это весьма сложная штука, изложенная скорее на языке алгебры, чем на языке нормальных людей. Не каждый программист готов в этом разобраться. Я, разработчик IDE, которому приходилось ковыряться в соответствующем коде, к своему стыду тоже довольно плохо разбираюсь в этой теме и понимаю процесс только по верхам. Причём сложно не только мне, но и авторам компилятора Java. После выхода Java 8 обнаружились десятки багов, когда поведение компилятора не соответствовало спецификации, либо текст спецификации был неоднозначен. В средах разработки для Java ситуация обстояла не лучше: там тоже были баги, причём другие, поэтому код мог отображаться ошибочным в вашей IDE, но успешно компилироваться. Или наоборот. С годами ситуация улучшилась, многие баги исправили, хотя всё ещё в спецификации остались тёмные углы.

Читать дальше →
Всего голосов 40: ↑40 и ↓0+40
Комментарии57

Сломать объект с помощью финализации

Время на прочтение3 мин
Количество просмотров8.2K

Вчера перевели в статус Candidate новый JEP 421: Deprecate Finalization for Removal. Путь к удалению механизма финализации из Java начался в Java 9, когда метод Object.finalize() был впервые объявлен deprecated. Рано или поздно механизм исчезнет из Java, поэтому если вы его используете, самое время задуматься об альтернативах. Однако статья не об этом.


Я думал, что довольно хорошо представляю себе все минусы механизма финализации. Многие из них перечислены, например, в этой статье. Однако, прочитав JEP, я узнал об уязвимости, о которой раньше и не думал. Оказывается, с помощью финализации можно создать объект со сломанными инвариантами.

Читать дальше →
Всего голосов 33: ↑33 и ↓0+33
Комментарии8

Сделать статический анализ умным — полдела, потом его надо делать глупым

Время на прочтение6 мин
Количество просмотров7.5K

Одна из проблем статического анализа в том, что его легко сделать умнее, чем надо. В результате он начинает выдавать предупреждения в таком коде, который человеку кажется нормальным. И так и хочется сказать анализатору «Отстань, зануда! Сильно умный что ли?»


Я в очередной раз почувствовал вкус всего этого, когда работал над поиском константных выражений для Kotlin. Ранее такой анализ был для Java, но для Kotlin он впервые появится только в следующей версии IntelliJ IDEA 2021.3. Инспекция базируется на анализе потока данных и находит в коде выражения, которые всегда равны одному и тому же. Изначально такая инспекция на Java сообщала только о логических выражениях, которые всегда равны true или false. Потом мы осторожно расширили её, и она стала сообщать ещё и о выражениях, которые всегда равны null или 0. Было решено проделать тот же путь для Kotlin.

Читать дальше →
Всего голосов 40: ↑38 и ↓2+36
Комментарии34

One does not simply calculate the absolute value

Время на прочтение4 мин
Количество просмотров32K

It seems that the problem of calculating the absolute value of a number is completely trivial. If the number is negative, change the sign. Otherwise, just leave it as it is. In Java, it may look something like this:


public static double abs(double value) {
  if (value < 0) {
    return -value;
  }
  return value;
}

It seems to be too easy even for a junior interview question. Are there any pitfalls here?

Read more →
Всего голосов 11: ↑10 и ↓1+9
Комментарии5

Нельзя так просто взять и вычислить абсолютное значение

Время на прочтение4 мин
Количество просмотров32K

Кажется, задача вычисления абсолютного значения (или модуля) числа совершенно тривиальна. Если число отрицательно, давайте сменим знак. Иначе оставим как есть. На Java это будет выглядеть примерно так:


public static double abs(double value) {
  if (value < 0) {
    return -value;
  }
  return value;
}

Вроде бы это слишком просто даже для вопроса на собеседовании на позицию джуна. Есть ли тут подводные камни?

Читать дальше →
Всего голосов 121: ↑118 и ↓3+115
Комментарии102

How to make debug-friendly method references

Время на прочтение5 мин
Количество просмотров4.2K

Java 8 introduced two kinds of functional expressions: lambda expressions like s -> System.out.println(s) and method references like System.out::println. At first, developers were more enthusiastic about method references: they are often more compact, you don't need to think up the parameter name, and, as urban legends say, method references are somewhat more optimal than lambda expressions. Over time, however, the enthusiasm waned. One of the problems with method references is the difficulty in debugging.

Read more →
Рейтинг0
Комментарии0

Как сделать ссылки на методы дружелюбными для отладки

Время на прочтение5 мин
Количество просмотров6.9K

В Java 8 появилось два вида функциональных выражений — лямбда-выражения вида s -> System.out.println(s) и ссылки на методы вида System.out::println. Поначалу ссылки на методы вызывали больше энтузиазма: они часто компактнее, вам не требуется придумывать имя для переменной, а ещё старожилы говорят, что они несколько оптимальнее, чем лямбда-выражения. Однако со временем энтузиазм ослаб. Одна из проблем со ссылками на методы — затруднённая отладка ошибок.

Читать дальше →
Всего голосов 21: ↑21 и ↓0+21
Комментарии3

Анбоксинг в современной Java

Время на прочтение5 мин
Количество просмотров20K

Сейчас новые версии Java выходят раз в полгода. В них время от времени появляются новые возможности: var в Java 10, switch-выражения в Java 14, рекорды и паттерны в Java 16. Про это всё, конечно, написано множество статей, блог-постов, сделано множество докладов на конференциях. Оказалось, однако, что мы все пропустили один очень крутой апгрейд языка - апгрейд обычного цикла for по набору целых чисел. Дело в том, что этот апгрейд случился не в языке, а в виртуальной машине, но заметно поменял на то как мы можем программировать на Java.

Вспомним старый добрый цикл for:

Читать далее
Всего голосов 63: ↑63 и ↓0+63
Комментарии63

Кто умнее чем IDEA?

Время на прочтение4 мин
Количество просмотров14K

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



И сказали, мол, ну раздай каким-нибудь людям на конференции на своё усмотрение. Я запаниковал. Как же я буду людей-то выбирать?


Тогда я довольно плотно работал с анализом потока данных в статическом анализаторе IntelliJ IDEA для Java. Во-первых, я обкатывал новые фичи, проверяя код самой IDE. Во-вторых, разгребал входящие баг-репорты. Иногда IDEA находила удивительные проблемы, и мне приходилось долго разбираться, чтобы вообще понять, правильное ли предупреждение она выдаёт или это баг.

Читать дальше →
Всего голосов 37: ↑36 и ↓1+35
Комментарии42

Статический анализ IntelliJ IDEA против человеческого разума

Время на прочтение4 мин
Количество просмотров13K

Не так давно я изучал вывод статического анализатора IntelliJ IDEA для Java-кода и наткнулся на интересный случай. Так как соответствующий фрагмент кода не является open source, я его анонимизировал и отвязал от внешних зависимостей. Будем считать, что он выглядел так:


private static List<Integer> process(Map<String, Integer> options, List<String> inputs) {
    List<Integer> res = new ArrayList<>();
    int cur = -1;
    for (String str : inputs) {
        if (str.startsWith("-"))
            if (options.containsKey(str)) {
                if (cur == -1) cur = options.get(str);
            }
            else if (options.containsKey("+" + str)) {
                if (cur == -1) cur = res.isEmpty() ? -1 :
                        res.remove(res.size() - 1);
                if (cur != -1) res.add(cur + str.length());
            }
    }
    return res;
}

Код как код, что-то преобразуется, что-то делается, но статическому анализатору он не понравился. Здесь мы видим целых два предупреждения:


Code screenshot

Читать дальше →
Всего голосов 52: ↑51 и ↓1+50
Комментарии26

Опыт перевода Maven-проекта на Multi-Release Jar: уже можно, но ещё сложно

Время на прочтение10 мин
Количество просмотров4.1K

У меня есть маленькая библиотека StreamEx, которая расширяет возможности Java 8 Stream API. Библиотеку я традиционно собираю через Maven, и по большей части меня всё устраивает. Однако вот захотелось экспериментов.


Некоторые вещи в библиотеке должны работать по-разному в разных версиях Java. Самый яркий пример — новые методы Stream API вроде takeWhile, которые появились только в Java 9. Моя библиотека предоставляет реализацию этих методов и в Java 8, но когда расширяешь Stream API сам, попадаешь под некоторые ограничения, о которых я здесь умолчу. Хотелось бы, чтобы пользователи Java 9+ имели доступ к стандартной реализации.

Всего голосов 31: ↑29 и ↓2+27
Комментарии16

Заменить Object на var: что может пойти не так?

Время на прочтение6 мин
Количество просмотров11K

Недавно я столкнулся с ситуацией, что замена Object на var в программе на Java 10 приводит к исключению в процессе выполнения. Мне стало интересно, много ли разных способов добиться такого эффекта, и я обратился с этим вопросом к сообществу:



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

Всего голосов 44: ↑43 и ↓1+42
Комментарии17

Отчёт с Java Virtual Machine Language Summit 2019

Время на прочтение14 мин
Количество просмотров6.2K

Сегодня закончился двенадцатый саммит JVM LS. Как обычно, это было хардкорное мероприятие с техническими докладами, посвящёнными виртуальным машинам и языкам, которые на них работают. Как обычно, саммит проходил в Санта-Кларе, в кампусе компании Оракл. Как обычно, желающих попасть сюда существенно больше, чем мест: количество участников не превышает 120. Как обычно, не было никакого маркетинга, только потроха.


Для меня этот саммит уже третий, и каждый раз я посещаю его с большим удовольствием, несмотря на ужасный jetlag. Здесь можно не только послушать доклады, но и познакомиться поближе с известными людьми из мира JVM, поучаствовать в неформальных беседах, позадавать вопросы на воркшопах и вообще почувствовать себя причастным к великим свершениям.


Если вы не попали на саммит, не беда. Большинство докладов выкладывают на YouTube практически сразу послед саммита. Собственно они уже доступны. Чтобы было проще сориентироваться, я опишу здесь вкратце все доклады и воркшопы, на которых удалось поприсутствовать.

Всего голосов 40: ↑40 и ↓0+40
Комментарии5

How We Find Lambda Expressions in IntelliJ IDEA

Время на прочтение10 мин
Количество просмотров7.2K

Type Hierarchy in IntelliJ IDEACode search and navigation are important features of any IDE. In Java, one of the commonly used search options is searching for all implementations of an interface. This feature is often called Type Hierarchy, and it looks just like the image on the right.


It's inefficient to iterate over all project classes when this feature is invoked. One option is to save the complete class hierarchy in the index during compilation since the compiler builds it anyway. We do this when the compilation is run by the IDE and not delegated, for example, to Gradle. But this works only if nothing has been changed in the module after the compilation. In general, the source code is the most up-to-date information provider, and indexes are based on the source code.


Finding immediate children is a simple task if we are not dealing with a functional interface. When searching for implementations of the Foo interface, we need to find all the classes that have implements Foo and interfaces that have extends Foo, as well as new Foo(...) {...} anonymous classes. To do this, it is enough to build a syntax tree of each project file in advance, find the corresponding constructs, and add them to an index.

Read more →
Всего голосов 11: ↑11 и ↓0+11
Комментарии0

Как мы в IntelliJ IDEA ищем лямбда-выражения

Время на прочтение10 мин
Количество просмотров13K

Type Hierarchy в IntelliJ IDEAВажной возможностью любой IDE является поиск и навигация по коду. Один из часто используемых вариантов поиска на языке Java — поиск всех реализаций данного интерфейса. Часто такая функция называется иерархией типов (Type Hierarchy) и выглядит как на картинке справа.


Перебирать все классы проекта при вызове этой функции — неэффективно. Можно сохранить в индекс полную иерархию классов во время компиляции, так как компилятор все равно ее строит. Мы это делаем, если компиляция запускается самой IDE, а не делегируется, например, в Gradle. Но это работает, только если после компиляции в модуле ничего не менялось. А в общем случае исходники — самый актуальный источник информации, и индексы строятся по исходникам.


Поиск непосредственных наследников — несложная задача, если мы не имеем дело с функциональным интерфейсом. При поиске реализаций интерфейса Foo надо найти все классы, где есть implements Foo, и интерфейсы, где есть extends Foo, а также анонимные классы вида new Foo(...) {...}. Для этого достаточно заранее построить синтаксическое дерево каждого файла проекта, найти соответствующие конструкции и добавить их в индекс.

Читать дальше →
Всего голосов 62: ↑59 и ↓3+56
Комментарии9

Проверка проекта CDK с помощью статического анализатора IntelliJ IDEA

Время на прочтение9 мин
Количество просмотров7.8K

Я решил потестировать статический анализатор Java-кода IntelliJ IDEA и с его помощью проверил проект The Chemistry Development Kit. Здесь я приведу некоторые ошибки, которые я нашёл. Думаю, что часть из них характерна для Java-программ в целом, поэтому могут быть интересны.


The Chemistry Development Kit — это Java-библиотека с открытыми исходниками для решения задач хемоинформатики и биоинформатики. Когда я занимался биоинформатикой, мы активно её использовали. Проект разрабатывается уже более 20 лет, у него десятки авторов, и качество кода там очень неровное. Тем не менее, в проекте имеются юнит-тесты, а в pom.xml прописана интеграция с анализатором покрытия JaCoCo. Вдобавок там настроены плагины целых трёх статических анализаторов: FindBugs, PMD, Checkstyle. Тем интереснее проверить, какие же предупреждения остаются.

Читать дальше →
Всего голосов 23: ↑23 и ↓0+23
Комментарии7

Как писать юнит-тесты, если совсем не хочется

Время на прочтение5 мин
Количество просмотров74K

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


Тем не менее злые начальники требуют больше тестов, говоря о так называемом «контроле качества». Особо хитрые менеджеры даже считают покрытие и не отпускают вас с работы, пока оно не будет достигнуто. Ваш код заворачивают на ревью, если в нём нет тестов или они чем-то не понравились. Сплошное расстройство!


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

Читать дальше →
Всего голосов 101: ↑92 и ↓9+83
Комментарии162

Редактор TECO: EMACS, я твой отец

Время на прочтение9 мин
Количество просмотров12K

Впервые про TECO я прочитал в пародийной статье Real Programmers Don't Use Pascal, написанной незадолго до моего рождения. Там было написано, что настоящие программисты не используют новомодные редакторы EMACS и VI:


Нет, Настоящий Программист хочет редактор вида «Просил? Так получай!» — сложный, загадочный, мощный, не прощающий ошибок, опасный. TECO, если быть точным.
Оригинал
No, the Real Programmer wants a `you asked for it, you got it' text editor — complicated, cryptic, powerful, unforgiving, dangerous. TECO, to be precise.

Это меня заинтриговало. Что за зверь такой, можно ли его пощупать? Википедия рассказала, что TECO — это Text Editor & COrrector, создан он в 1962-м году в DEC и использовался на компьютерах семейства PDP, а позже на системах OpenVMS. Оказалось, что существует порт на Си, который поддерживается энтузиастами в актуальном состоянии и собирается под современными операционными системами. Вот я и решил почувствовать себя настоящим программистом хотя бы немножко.


Читать дальше →
Всего голосов 54: ↑53 и ↓1+52
Комментарии9

Задача про forEach(ps::println) от СКБ Контур

Время на прочтение9 мин
Количество просмотров15K

На конференции JBreak я не читал задачки спонсоров специально. Ну, конечно, кроме ада от Excelsior: уж эти ребята всем задали жару. А тут принесли мне листок от СКБ Контур, смотри, мол, посмейся. Я посмеялся: первая задача действительно выглядела настолько наивно сформированной и недоопределённой, что даже не хотелось идти к стенду и убеждать в этом сотрудников компании. Я про это почти забыл, однако тут на Хабре появился авторский разбор этой задачи, не лишённый некоторой глубины. Даже про modCount написали. Выходит, зря я смеялся?

Читать дальше →
Всего голосов 43: ↑43 и ↓0+43
Комментарии8

Мозаика в ванной и диофантовы уравнения

Время на прочтение4 мин
Количество просмотров26K

Дело было вечером, перед сном. Чистил я зубы и устало разглядывал мозаику в ванной. Почему-то меня заинтересовал такой простой факт: если прямоугольник из клеточек 2×3 обвести с двух сторон ещё клеточками, то площадь обводки окажется такой же как площадь прямоугольника:




Голубых квадратиков ровно столько, сколько жёлтых. И тут меня понесло.
Читать дальше →
Всего голосов 95: ↑92 и ↓3+89
Комментарии19

Информация

В рейтинге
Не участвует
Откуда
Новосибирск, Новосибирская обл., Россия
Зарегистрирован
Активность