Pull to refresh
4
0
Владимир Ситников @vladimirsitnikov

Пользователь

Send message

"6. Рандомизация в тестах". Вам там property-based testing https://en.m.wikipedia.org/wiki/Software_testing#Property_testing и фаззинг https://ru.m.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B7%D0%B7%D0%B8%D0%BD%D0%B3 показывают, а вы отнекиваетесь, что "не надо писать рандомизированные тесты". Надо. Надо их писать. Вот пример с недавнего Гейзенбага: https://youtu.be/fbhuzSpyUJc.

Почти в любой системе количество входных данных таково, что полный перебор всех возможных вариантов никогда не закончится. И рандомизация (особенно, если она с учётом граничных значений, coverage guided, и так далее) может тестировать новые и новые данные с каждым запуском. Всех случаев не проверишь но 1-5 минут рандома на каждый pull request и рано или поздно ошибка найдётся.

Если Котлин, то при чём тут Си?

На самом деле, статья и начинается со слов, что в Java анализатор уже написан и отлажен, поэтому с Java сравнивать логично.

Если код закомментировать, то он может перестать компилироваться, поэтому if false зачастую лучше, чем комментирование кода

В Java language specification отдельно описано, что if (false) это годный код, и компилятор не должен ругаться на его недостижимость: https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

Думаю, ни там ни там не надо. Разумеется, "правильного ответа" тут нет, и как партия решит, так пусть и будет. Но я всё равно думаю, что подкрашивать условие if(false) это странно. Вполне нормально взять и написать while(false), if(false) и т.п. для отладки. Если оно более блеклым цветом отметит "никогда не выполняющиеся ветки кода", то это другой разговор. А подкрашивать "if(false) is always false" -- ну, зачем?

Не, объявить val debug=false и бранчеваться -- самая тема. Поэтому, да, соглашусь, что ругаться на if (debug) не стоит. Поэтому же и считаю, что ругаться на if (false) не должно. Тут же по-человечески написано false. Зачем лишний раз сообщать, что "condition is always false"? :)

"condition is always false". И quick-fix там -- "delete expression"

Хотя посмотрел на Java -- там if (false) ругается (почему бы?). Наверное, если уж делать, то однообразно.

Тема статьи какая? "Вот нормальный код, анализатор пытался его обругать, но не надо было". А тут смотришь -- и между строк написано "тут должно было быть isNullOrEmpty".

Я другое спрошу (213.4631.20, 6 October). Почему на if (false) ругается, что "condition is always false", а на val x = false; if (x) уже нет? Бага получается? Я бы на if (false) и if (true) не ругался.

Ну ты зануда

Ты меня раскусил

Ну представь, что там исключение кидается. Лучше будет?

Исключение прекрасно кинется в when else ветке. Ну, тут я полностью соглашусь, что корень проблемы не в "expression is always true", а в том, что тут возникло дублирование логики, и, вполне возможно, это дублирование следует убрать, чтобы перечни статусов не разошлись (ну, вдруг добавят ветку в when, а if забудут поправить?). Но, если бы у меня в том when "low" возникло предупреждение "condition is always true", то я бы порадовался и сказал: "а, действительно, как так получилось, что always true" и пошёл бы и убрал if или что там.

А смысл? Предупреждения должны нести смысл. Если над каждым придётся думать, то смысла в них никакого не будет. Так-то в каждой строке можно предупреждение придумать: "вы точно уверены, что тут переменная x, а не y?"

Возможно, что 99.42% всех таких примеров сведутся к тому, что незачем там return внутри let использовать, и оно должно ругаться словами "убирайте return" или "убирайте let"

val empty = str?.isEmpty() ?: true if (!empty && str != null) { // 'str != null' is always true

Что только люди не напишут, лишь бы не делать по-простому (штатный механизм в stdlib): if (str.isNullOrEmpty()) { ... }

Например, перед when могло быть общее действие, которое надо сделать для всех трёх вариантов. Давай что-нибудь добавлю

По-моему, всё равно if лишний. Убрать бы его. Получается, кто-то там может слать недопустимые значения, а мы их игнорируем. Конечно, так и до enum недалеко додуматься, но вопросы остаются.

Если уже 25 вызовов с одним значением ignoreCase, то пора extract method делать.

Разумеется, я поддерживаю, что ругаться должна инспекция "вы тут зря переменную завели, воспользуйтесь лучше именованными параметрами", а не "expression is always true", просто исходно код выглядит стрёмно, и зачастую ожидаемо, что анализатор будет что-то там бурчать, особенно, когда код стрёмный.

Пример про isOption, конечно, нужно вообще без return записывать. Там ни return ни let не нужно: `isOption(s: String?) : Boolean = s?.startsWith("--") ?: false`. Ну или на String.isOption переделать (но это уже от проекта зависит)

А зачем в updatePriority примере нужен был if? Если его убрать, то станет проще читаться и будет проще поддерживать (не придётся дублировать литералы). Правильно оно ругалось на код, по делу.

command.startsWith("--data", ignoreCase) -- тоже по делу ругалось. Если хочется пояснить ignoreCase, то почему бы не использовать для этого именованные параметры? Зачем переменную объявлять? Вот так хорошо: command.startsWith("--data", ignoreCase = true)

В Java 8+ лучше использовать java.lang.Integer#remainderUnsigned. И биты не теряем, и проблем с отрицательными значениями нет.

Иерархические метки это метки со слешами вида папка / новая папка / новая папка (2)?
На самом деле, логики никакой нет. Это просто особенность реализации PostgreSQL, которая заключается в том, что при завершении транзакции все курсоры превращаются в тыкву

Например, в Oracle DB курсоры без проблем переживают операцию commit и продолжают возвращать согласованные данные. Можно открыть курсор, сделать commit (или несколько) и без проблем продолжать выборку из курсора. Разумеется, у долгих курсоров есть шанс наткнуться на ORA-01555 snapshot too old, но это другая история.

Разработчики PostgreSQL почему-то посчитали, что, если транзакцию закрываем, то и курсоры нужно обязательно закрыть. При этом, фиксация транзакций в параллельных потоках никак не влияет.

Типичный подход в Oracle мире для batch обработки: открываем курсор, выбираем 10'000 записей. Обрабатываем, меняем данные, выполняем commit. Выбираем следующие 10'000 (операцией fetch bulk collect into… limit 10000) и так далее. Это позволяет не выполнять выборку каждый раз с нуля, и «выбирающий» курсор не протухает. В PostgreSQL такой подход не работает.
Во. Про такое тоже стоит упоминать.
Я почему-то считал, что это всё портировано и в 8
миграция на JDK13 и использование сборщика мусора Shenandoah

Это связанные события или нет?
Shenandoah разлива JDK 8/11 не хватает? Или в JDK13 есть что-то дополнительное?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity