Хороший институт не даёт хорошего образования

Где лучше учат, в Стенфорде или в академии ШАГ а может и вовсе на дешёвых курсах?

Не имеет никакой роли. Вот прям совсем. Как бы тебе не разжёвывали, тебе всё равно придётся самому это «проглотить». Чему бы тебя не учили — почти невозможно придумать идеальную программу которая подходит всем. Как бы хорошо ты не запомнил — ты всё равно забудешь без практики.
Невозможно сказать что факультет плохой или хороший. Может быть хороший преподаватель — но его «хорошовизна» может определятся только его способностью определить что нужно студенту и подогнать обучающую программу под него. Это то что называется «объясняет».
Более того, может быть реально прекрасный преподаватель, но его стиль обучения не совпадает со стилем обучения студента.
Давайте я объясню подробнее что я имею в виду. Например у меня стиль обучения такой: я не читаю никаких книжек и вообще ничего. Я тупо «интуитивно» пытаюсь угадать как должно быть и пытаюсь это сделать.
Я делал довольно сложные программы, и при этом неплохо написанные и удачно декомпозированные при этом вообще не понимая ООП. Более того, у меня даже книжки не было по Делфи.
Но со временем у меня вдруг включается другой режим — и я вдруг вчитываюсь в матчасть и подробно её изучая. При этом когда читаю документацию я её как бы сканирую и пытаюсь найти «потаённые» штуки которые могут мне пригодится.
Я пытаюсь первым делом понять как и для чего использовать эти знания, а потом уже изучаю их глубже только ради того чтобы узнать как можно ещё лучше их использовать. Сами по себе мне эти знания не очень-то интересны.
Т.е. мой стиль обучения мне помогает в моей работе программиста — я так быстро осваиваю технологии и перехожу с одной на другую. Но мне бывает очень тяжело изучить что-то в деталях.
И я прям совсем не могу быть, что называется, учёным. Мой мозг бунтует и отказывается принимать знания если я не понял как конкретно их применять. И я бы никогда бы не смог заниматься наукой ради науки. Люди вроде Буля, который придумал дискретную алгебру, для меня какие-то прям супергерои — они придумали что-то, что нашло применение только столетия спустя.
Теперь смотри, я такой студент, я мотивирован, я что-то там может даже соображаю. Но мой преподаватель даёт информацию подробно разжёвывая с объяснением. Например мы проходим побитовые операции. Мне они не интересны, но мне подробно и очень хорошо рассказывают все эти нюансы. Я начинаю скучать и тупо вырубаюсь на лекции.
С формальной точки зрения — я получил отличное образование. С практической полный ноль.
Я был бы неуспевающим и меня бы отчислили.
Я не очень ковырял эту тему но видел какие-то более менее вменяемые объяснения что такое Стиль обучения в соционике и на Википедии.
В действительности я насколько понимаю эта область граничит с нейробиологией, психологией и педагогикой и довольно слабо изучено.
Поэтому нужно просто признать — сегодня наверное никто не знает как правильно учиться и учить.
Это настолько индивидуально и требует длительного наблюдения что с этим смогут справляться только когда технологии Big Data помогут проанализировать и делать какие-то статистически подтверждённые утверждения как эффективно учить.
А теперь умножьте это на компьютерные науки которые сегодня являются во многом синтетическими а не природными, а значит могут сильно меняться и отличаться. И во много являются «алхимией», «шаманством» или «искусством», т.е. мы признаём что тупо не знаем как оно работает и должно проектироваться.

Как определить что вы учите примерно правильно и примерно оптимально, по крайней мере для определённой категории людей? Очень просто — если вам платят значит вы в правильном направлении. Если вам платят значит ваши студенты всё таки имеют больше шансов на устройство. Если они устраиваются значит они могут справляться с работой.
Рынок, рынок всё решает.

По мотивам обсуждения на форуме Стремительный рост КА ШАГ

ржавые часы

А у вас есть баги на переход к летнему времени?

Сегодня на работе внезапно упал билд — не прошёл один тест на какой-то древней странице админки. Тест был простым и проверял функциональность фильтра по дате. Есть метод который проверяет что между двумя датами есть хотя бы один день. И код примерно такой:

/** Minimal range between dates is one day */
boolean checkMinDatesRange(Date dateFrom, Date dateTo) {
  long millisecondsBetween = dateTo.getTime() - dateFrom.getTime());
  int daysBetween = millisecondsBetween / (1000 * 60 * 60 * 24); // roundinig to int
  return daysBetween >= 1;
}

Как вы уже могли догадаться это воскресенье было последним в марте и перевели стрелки на час вперёд, на летнее время.
В результате millisecondsBetween стало меньше на 36000 миллисекунд и после округления до целого daysBetween стал равен нолю а не ровно один, как ожидал тест.
Отчасти этот код вызван тем что в Java долгое время было просто ужаснейшее Date API и в каждом проекте появлялись свои DateUtils кишащие такими проблемами.

Лечится это через JodaTime или JavaTime примерно так:

int daysBetween = Days.daysBetween(dateFrom, dateTo).getDays()

Тебе ещё не страшно?

Хорошо что этот баг был не критичным, но я уверен что почти в каждой системе есть подобные баги. Например:

  • В отчётах круглосуточных онлайн сервисов сумма за день становится больше или меньше чем нервирует тех кто по ним делает проплаты.
  • В огромных распределённых базах (как у твитера или фесбука), где вместо удаления\апдейта записи создаётся новая с последним временем может поменяться порядок записей и последняя, правильная запись потеряется. Поэтому в распределёнках используются таймштампы и админы следят за синхронизацией времени на всех серверах.
  • Один сервер по крону выкладывает данные ночью в три вечера, другой сервер, из другой таймзоны через 15 минут попытается забрать — а из-за перевода там ещё ничего нет.

И такие приколы не только с переводом стрелок, а например с високосным годом, или високосной секундой.
И ладно если вы это ещё кое-как всё написали правильно, но может быть такое что часы не перевились, а то и вовсе батарейка в BIOS села и часы всегда показывают один и тот же день.

А теперь представьте что на АЭС перегретый реактор начнёт гасится графитовыми стержнями на час позже из-за того что часы перевелись на час вперёд? Или поезда на встречу друг другу выехали.
Я программист, и видел уже достаточно кода чтобы боятся таких катастроф.

Например в прошлом году секунда координации вызвала сбои в работе Android, Twitter, Amazon, Netflix и других крупных компаниях где работают весьма толковые программисты.

И это кстати интересная проблема возникает с этой секундой — Земля то, постепенно затормаживается. И потенциально может перестать крутится вообще (т.е. в сутках будет бесконечное число часов), или крутится в обратную сторону (отрицательные часы). Тогда как вообще считать время?

Ну до ладно, это допустим ещё не скоро настанет.
Но уже сейчас есть проблема: релятивистское замедление времени на спутниках. Космонавты когда возвращаются на Землю по сути попадают из прошлого в настоящее. Пространственно-временной континуум — это ещё поди разберись с ним.

Переводим время на перевод времени

И если с секундой координации никуда не деться, её всё равно куда-то придётся приписывать, то вот переходы на летнее и зимнее время это одно из самых дебильных введений.
Зачем переводить? Официально говорят «ну чтобы энергию беречь». Так а как вы её сбережёте? Всё равно свет будете включать когда потемнеет, а не когда часы скажут. График работы тоже можно корректировать не обращая внимание на время. Всё равно, например рестораны, летом работают дольше.
Фермеры всё равно будут вставать с петухами.
Ну допустим, это удобно что у всех организаций синхронно меняется график.
Но почему тогда перевод стрелок только два раза в год? Летом же солнце всё равно в четыре встаёт, даже с учётом сдвига. Так давайте каждый день переводить стрелки? Чтобы наверняка с первыми лучами все шли на работу. Например в Японии в ответственных случаях работа должна начинаться только через 2 часа после восхода солнца, например, при сдаче экзаменов.

А как быть с теми кто в Заполярье если у них вообще белые ночи и дни? Или тем кто на экваторе, они вообще разницы не заметят.

Ладно, допустим они решили всё равно ввести переход на летнее время. А они вообще подумали как уговорить весь мир перейти тоже?
Вот мы и имеем что в разных странах, да даже в разных областях и провинциях по разному. И разница во времени получается по несколько часов разницы во времени.

Это абсолютный бред и у меня с детских лет кошмарное ощущение что вокруг одни идиоты которые этого не замечают.

Эту дурь придумал какой-то британский мудак которому, видите ли, было обидно в гольф играть в темноте. И вместо того чтобы раньше приезжать он решил что всем нужно под его дудку плясать. Целую жизнь на это положил, не зря прожил, герой.

Как ею могло заразится остальное человечество я не понимаю.
Ещё и исследование какие-то делают на эту тему, кто-то считает количество инсультов, парламентарии спорят, то вводят то отменяют переход. Считают какие-то убытки и экономию.
Это как вообще такое может быть? Что за помешательство?

ИЧСХ все такие прям умные и прогрессивные что-то там якобы считают а по факту потом просто какие-то мудаки у власти принимают решение о переходе просто так, с бухты-барахты.
Сначала во после революции 1917го года матросы начали декреты вводить и выводить. Ну ладно, это была эпоха модерна.
Но блин, уже в наши дни цирк продолжился: «На встрече с молодыми учёными 8 февраля 2011 года президент Медведев объявил о своём решении отменить ежегодный перевод часов, начиная с отмены возврата на «зимнее» время осенью 2011 год. В соответствии с этим решением были подготовлены и приняты Федеральный закон «Об исчислении времени» и постановление правительства. Летнее время осталось в качестве постоянно действующего».
Вот так, царю взбрело в голову и быстренько приняли закон какой надо. Только дебилу было невдомёк что правильное время — это зимнее, а не летнее.
Но кого такие премудрости интересуют, верно?Ввели сразу и бесповоротно, естественно бюрократы не спрашивали у технарей проверили-ли они свои программы и системы. Сколько сбоев и убытков было принесено, а возможно и жизней, никого не интересовало.
Зато опять провели важное исследование и соцопрос где выяснилось что «реформа не нашла поддержки у значительной части населения». Да ну?

Но цирк на этом не закончился, и говно полетело по трубам:
«Вскоре за Россией последовала Белоруссия.
Верховная Рада Украины 20 сентября 2011 года отменила переход на «зимнее» время с целью сохранить летнее время постоянным, однако 18 октября 2011 года отменила своё решение, и перевод часов состоялся в положенное последнее воскресенье октября. (Успели, бараны, отменить за неделю до перевода).
Вслед за первоначальным решением Украины, и мотивируя решение необходимостью жить в одном времени с Украиной, от перевода часов отказалось Приднестровье. Но потом, вслед за Украиной, в Приднестровье перевод часов был продолжен.»

Но и на этом цирк не закончился и в 2014м году в РФ вернулись на постоянное «зимнее» время.

Я это всё наблюдал внимательно каждый раз всё больше и больше офигевая.

Программист помни: время безжалостно к нам

Изучи матчасть, хотя бы эту:

Всегда перед переводом стрелок инспектируй код на предмет возможных пропущенных проблем. Я создал календарь где добавил напоминание на осень перепроверить.

Знай, что в любой момент эти безумные твари снова захотят отвлечь лохов и поменяют часовой пояс или сделают тебе осеннее время. Или оккупируют тебя, например.
Следи что в твоей системе обновляется tz database и обрати внимание чтобы даты в ОС и БД совпадали, как и на других серверах. Учти что ОСи могут тоже долго не обновлять и тогда нужно делать конфиги или хранить их в БД.

Не верь что всегда будет 24 часа. Не рассчитывай вообще ни на что. Когда нибудь, в Землю обязательно врежется астероид и это изменит траекторию.

И помни, грядёт 2038 год!

Скринкаст: Пишем калькулятор на Java, JavaFX, Groovy, Spock, Kotlin

Несколько вечеров за которые я написал калькулятор на Джаве с тестами на Груви а потом переписал на Котлин. Интересно будет только для Stong Junior’ов

Это не туториал! В обычных туториалах всё хорошо и сразу получается, но как только начинающий программист сталкивается с ошибкой то не знает как дальше двигаться. Здесь все по настоящему — часть я знаю, часть изучаю сразу же. На ваших глазах появляются и фиксятся баги, гуглится и копипастится с СтекОверфлоу. Это может быть вам полезно для того чтобы ощутить эвристики которые помогают мне.
Скучно, занудно — но именно так примерно мы и программируем целыми днями. Если вы думаете связать свою жизнь с этим ремеслом, можете прочувствовать себя в моей шкуре😉

Исходный код:
https://github.com/stokito/javafx-calculator

P.S. Да, я знаю звук отвратительный, винда неудачно обнволялась и с драйвером звука какая-то ерунда.

junit, test-ng, mockito, spock

Spock or not to Spock?

В последнем выпуске подкаста Разбор полётов ведущие спорили насколько оправданно применять тестовый фреймворк Spock для всех Java проектов.
Изначально разговор зашёл про спецификации и программные TCK которые проверяют что имплементация соответствует спецификации.
Тут пожалуй стоит сделать отступление, и отметить что обычно также делают referrence implementation и как минимум ещё одну реализацию, поскольку любой API нужно реализовывать всегда как минимум дважды чтобы увидеть не появляется ли повторяющийся вспомогательный код перед вызовом API метода который следовало бы тоже вынести в API.
Например, в Java SE для такой частой операции как чтение текстового файла в строку приходилось постоянно писать код преобразования InputStream в StringBuilder и у него уже брать toString(). И только в седьмой джаве появился метод Files.readAllBytes() тем не менее по прежнему требующий ещё дополнительной строчки преобразования массива байтов в строку с указанием кодировки.

Ещё один важный момент, что TCK являются для реализации внешними тестами, в то время как у неё могут быть свои собственные, тестирующие именно особенности реализации.
Я это всё расписал чтобы иметь более полную картину.

И тут у ведущих возник естественный вопрос: если у нас уже есть программный TCK, то, по сути, он уже и есть вообщем-то спецификацией, только записанной уже в более формальном языке программы.
Это совершенно правильная мысль. Единственное различие в них в том, что спецификация является текстом описывающим систему для людей, на естественном языке, в то время как от TCK требуется только дать однозначный ответ — соответствует реализация спецификации или нет. И очень вероятна ситуация когда по коду TCK мы вообще не сможем понять почему все работает именно так, поскольку детали опущены в коде TCK но расписаны в самой спецификации.
Вообще тут даже можно утверждать что refference implementation и тесты самой реализации тоже так же могут служить заменой или дополнением спецификации.
Это одна из причин почему программисты так любят open source — ты всегда можешь узнать как точно работает система на которую ты полагаешься.

Следовательно идея совместить спецификацию и тесты и сделать их ближе к коду родила BDD.
Обычно в BDD фреймворках пишут сценарий на, хоть и формализованном, но естественном языке а потом к нему пишут тестовый код.
Вот пример такого сценария на языке сценариев Gherkin для фреймворка Cuccumber:

Story: Returns go to stock

In order to keep track of stock
As a store owner
I want to add items back to stock when they're returned

Scenario 1: Refunded items should be returned to stock
Given a customer previously bought a black sweater from me
And I currently have three black sweaters left in stock
When he returns the sweater for a refund
Then I should have four black sweaters in stock

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

private Game game;
private StringRenderer renderer;

@Given("a $width by $height game")
public void theGameIsRunning(int width, int height) {
game = new Game(width, height);
renderer = new StringRenderer();
game.setObserver(renderer);
}

@When("I toggle the cell at ($column, $row)")
public void iToggleTheCellAt(int column, int row) {
game.toggleCellAt(column, row);
}

@Then("the grid should look like $grid")
public void theGridShouldLookLike(String grid) {
assertThat(renderer.asString(), equalTo(grid));
}

Но например для Groovy, динамического языка программирования поверх JVM многих ограничений Java нет. И поверх него был создан прекрасный фреймворк Spock. Вот пример теста\спецификации:

class HelloSpock extends spock.lang.Specification {
def "length of Spock's and his friends' names"() {
expect:
name.size() == length

where:
name | length
"Spock" | 5
"Kirk" | 4
"Scotty" | 6
}
}

Это data driven тест с двумя секциями expect и where. В секции expect мы пишем выражение которое проверяем, а в секции where мы объявили набор данных из трёх имён которые будут последовательно подставляться в это проверочное выражение expect.
Имя тестового метода объявлено в кавычках и может содержать пробелы и записано в человекочитаемом виде.

Он оказался настолько хорош, что один из ведущих, Барух, выдвинул тезис что именно Spock следует применять во всех проектах на Java для тестирования.
Из моего опыта я могу полностью подтвердить что это качественно новый уровень удобства тестирования недоступный другим фреймворкам и я полностью согласен с Барухом.

Но тут возникает несколько опасений.
1. Не все захотят изучать новый язык программирования Groovy для всего лишь тестов.
Я считаю что Groovy, в оличие от например Scala, это просто диалект Java. Почти любой код на Java является валидным кодом на Groovy. Можно прям взять файл и поменять расширение с .java на .groovy и он скомпилится. Поэтому по сути программистам можно даже не выучивать его для написания тестов.
Groovy очень простой и выразительный язык, имеющий знакомый всем синтаксис, довольно прямолинейный и обладающий отличной «вкуриваемостью».
Есть совсем небольшой гайд для тех кто переходит с Джавы и несколько статей на подобии Groovy за 15 минут. Как по мне, самое главное и что стоит выучить поскольку оно моментально сокращает код в разы (а то и в десятки раз!) — это литералы [] для коллекций и [:] для map, работа с коллекциями, null safe navigration и Groovy Truth. Выучив только эти вещи у вас будет Quick Win.

У меня был случай когда я устроился на работу Java девелопером где в описании вакансии было скромно сказано «будет плюсом знание Groovy & Grails». Я даже особо внимание не обратил, подумал что может где-то у них есть проект и может меня доучат и попросят там помочь. На собеседовании были стандартные вопросы по Джаве.
И в первый же рабочий день мне дали задание написать небольшой функционал на Groovy. Уже через час мой код был оттестирован, проревьювлен и закомичен.
Конечно, очень много времени потом ушло на разборки с всплывшими подводными камнями, всякие тонкости и выработки оптимально стиля кодирования. Также мне потребовалось изучить механизмы метапрограммирования для создания всевозможных DSL’ов.
Но, тестовый код — он всегда простой. Обычно тебе всё что нужно это вызвать метод и сверить с ожидаемым результатом. Поэтому если у вас продакшен код написан на стандартной Джаве а тесты на Груви то вы почти наверняка не столкнётесь с никакими проблемами и глубже его изучать не будет нужды.
Груви подключается как обычная dependency к проекту и имеет отличную поддержку в IntelliJ Idea. А для Спока в неё ещё есть плагин который правда непонятно зачем нужен.
По своему опыту могу сказать что мне было намного труднее вникнуть в стримы восьмой Джавы чем выучить Груви. Учитыая количество подводных камней даже JavaScript в разы будет сложнее Груви.
Так что если какой-то из разработчиков не сможет постигнуть премудрости Груви для написания тестов то он просто совсем некомпетентен.

2. Груви динамический язык, и хотя и есть возможность помечать классы как @CompileStatic но это не работает в Spock
Да, это так и потенциально есть вероятность что если, например, вы поменяли в продакшен коде имя метода а тестах забыли то в момент компиляции ошибка останется незамеченной.
Но, это совершенно не критично — вы сразу же увидите ошибку когда запустите тест и он завалится.
Кроме того, если пользоваться автоматическим рефакторингом в Idea то таких ошибок даже не возникнет.
Так что проблема совершенно надуманная.

3. Что такого даёт Спок что ради него стоит заморачиваться?

Спок тебя строго заставляет писать тесты в правильной структуре, например строго выдерживать секции given:, when:, then:. Я очень часто видел в тестах на JUnit когда эти логические секции то и дело смешиваются и программисты ленятся выносить их отдельный тест кейс.
Кроме того, все строки в секции then: автоматически являются assert и в совокупности с Groovy Truth это убирает кучу ненужного кода и читабельность невероятно возрастает.

И тут нужно внимательно остановится на асертах. В Споке появились так называемые Power Asserts — штука настолько потрясающая, что её позже перенесли в сам Groovy а позже и на другие языки программирования, но к сожалению кроме Джавы.
Вместо тысячи бестолковых assertEquals(), assertTrue() и всяких матчеров типа Hamcrest в Груви достаточно просто написать ключевое слово assert и вы получите подробный вывод что и где пошло не так:

assert [[1,2,3,3,3,3,4]].first().unique() == [1,2,3]

// Output:
//
// Assertion failed:
// assert [[1,2,3,3,3,3,4]].first().unique() == [1,2,3]
// | | |
// | | false
// | [1, 2, 3, 4]
// [1, 2, 3, 4]

На практике это просто Вау фича! Причём теперь фича самого Груви, так что даже обычный JUnit тест на Груви будет в тысячу раз приятнее.

Ну и лично моя самая любимая фича, это data driven tests. Спок даёт простой и удобный DSL для быстрого написания набора тестовых наборов. Я уже приводил пример выше, но у Николая Алименкова возникло сомнение насчёт их идеалогической правильности.
Когда один из наборов из where: не проходит то весь тест кейс помечается как failed, даже если остальные проходили.
В результате репортинг становится не очень полезным.

Если вы хотите видеть детальный отчёт какой именно тестовый набор провалился, вы можете пометить тест кейс аннотацией @Unroll.
Но Николай вполне справедливо заметил: хорошо, теперь я буду знать какой конкретно тестовый метод не прошёл, но я не буду знать почему, ведь комментария нету.
Следовательно для того чтобы оставить комментарий всё равно придётся дата дривен тест разбивать на несколько тест кейсов.

Когда я столкнулся с точно такой же проблемой я тоже расстроился и хотел было уже разбивать несколько тест кейсов когда смекнул как это красиво решить.
К аннотации @Unroll можно передать шаблон в который будут вставляться значения из data table. И ничто нам не мешает в дата тейбле сделать ещё одно поле с комментарием.
Например, допустим у нас есть валидатор пароля и тест на него может выглядеть так:

@Unroll
def 'checkPassword(#password) valid=#valid : #comment'() {
given:
PasswordValidator validator = new PasswordValidator()
expect:
validator.validate(password) == valid
where:
password | valid | comment
'pwd' | false | 'too short'
'very long password' | false | 'too long'
'password' | false | 'Not enought strength'
'h!Z7abcd' | true | 'valid password'
}

Чётко, кратко и по делу. Такой же тест на JUnit был бы больше в четыре раза и в десять раз менее читабельнее.
Легкость создания дата дривен тестов тебя прям подталкивает их писать — обычно нужно всего-то лишь добавить одну строчку.

В JUnit для этого приходится мучаться параметризированными тестами и почти всегда никто этим просто не заморачиватся.
В результате множество кейсов остаются непокрытыми и множество багов проходят на продакшен.

Я например писал тесты для Grails Cookies плагина и просто посмотрите сколько кейсов в нём покрыто CookieResponseSpec.groovy.

Кроме этого в Споке есть ещё множество приятностей, например моки которые делают жизнь намного лучше. В нём всё построенно на DSL с которым придётся немного подразобратся, но его немного и он легко запоминается.

Вообщем, подытожу немного перефразировав Баруха: Если вы пишете тесты не на Споке — вы занимаетесь хернёй.

Кстати сегодня выйдет пятая версия JUnit с поддержкой лямбд. Я хоть и донейтил даже на этот проект, но посмотрел на документацию и взгрустнул.
В обозримом будущем в мире Джавы пока ещё даже не предвидеться ничего лучше чем Спок.

Antipatern: Negatively named boolean method

There is an inspection Java | Data flow issues | Negatively named boolean variable

Reports negatively named variables, for example ‘disabled’, ‘hidden’, ‘isNotChanged’. It is usually more clear to invert the boolean value and remove the negation from the name.

But no any inspections for methods.
For example the Apache Commons Lang library’s StringUtils class has two methods: isBlank() and isNotBlank(). The second one has a negativation «Not» and works like !isBlank().
This is antipattern, because we can use automatic refactoring from intellij to invert condition that calling this method.
I mean this refactoring Invert Boolean and Invert If-Else Statement intention.
For examle we can invert a conditionwith isBlank():
invert-if-condition
And result of this refactoringwill be:
invert-if-condition-result

But if you invert a condition with isNotBlank() you willl get a double negativation smell:
invert-if-not-condition
Now it’s readed as «not not blank» (i.e. blank).

Another one solution is to use method names that hasn’t inversion, for example hasText()

 

Please, avoid this in you code
We will create an Inspection for IntelliJ Idea that will check this cases