Статический анализ кода, часть 1. Основные метрики
Главная цель принципов разработки и паттернов проектирования — снизить стоимость разработки. Хорошим считается код, который легко:
🔸читать
🔸менять
🔸тестировать
🔸переиспользовать
Простота - субъективное понятие. Разработчику, который в проекте со дня основания, легко ориентироваться в коде и исправлять ошибки. Джуниор, который недавно пришёл и получил первое задание, вряд ли с ним согласится. К счастью, есть объективные показатели качества кода, которые можно отслеживать и анализировать. Их получают с помощью статического анализа на основе исходного и байт-кода. Базовых метрик больше 50, и обычно они группируются в 4 категории:
1️⃣ Связность (Cohesion)
Показывает, насколько сильно внутренние элементы взаимодействуют друг с другом, насколько сфокусирован класс.
В классе с низкой связностью много методов, которые мало взаимодействуют между собой:
2️⃣ Связанность (Coupling)
Показывает, как одна сущность взаимодействует с другими. Класс А связан с классом Б, если в классе А
▫️Поля класса Б
▫️Вызов методов класса Б
▫️Локальные переменные класса Б
▫️Если класс А - подкласс Б
В большинстве проектов есть модуль base или common - часто он является примером сильной связанности. Менять такой модуль - всегда большой риск.
3️⃣ Сложность (Complexity)
На этот показатель влияет:
▪️Сколько сущностей взаимодействуют
▪️Количество операций в методе
▪️Глубина наследования
▪️Количество ветвлений и возможных состояний
Показатель сложности часто идёт рука об руку с размером, но не всегда. Сложный метод может быть небольшим по размеру, но скрывать внутри себя десятки вариантов развития событий:
Большие сущности сложно поддерживать. В этой категории много метрик, например, количество:
🔹Полей
🔹Методов
🔹Статических методов
🔹Подклассов
🔹Связанных библиотек
А теперь ответы на вопросы перед постом:
✅ Если класс А часто использует класс Б, то это признак высокой связанности. Связанность (coupling) характеризует внешние отношения между сущностями. Связность (cohesion) - про внутреннюю структуру самой сущности.
✅ На сложность влияет количество ветвлений и глубина наследования. Остальные характеристики относятся к категории "размер".
Главная цель принципов разработки и паттернов проектирования — снизить стоимость разработки. Хорошим считается код, который легко:
🔸читать
🔸менять
🔸тестировать
🔸переиспользовать
Простота - субъективное понятие. Разработчику, который в проекте со дня основания, легко ориентироваться в коде и исправлять ошибки. Джуниор, который недавно пришёл и получил первое задание, вряд ли с ним согласится. К счастью, есть объективные показатели качества кода, которые можно отслеживать и анализировать. Их получают с помощью статического анализа на основе исходного и байт-кода. Базовых метрик больше 50, и обычно они группируются в 4 категории:
1️⃣ Связность (Cohesion)
Показывает, насколько сильно внутренние элементы взаимодействуют друг с другом, насколько сфокусирован класс.
В классе с низкой связностью много методов, которые мало взаимодействуют между собой:
class Программист {
void написатьКод()
void помытьПосуду()
void погладитьКота()
}
Идеальная сущность с точки зрения Cohesion - лямбда-выражение. Их легко читать, тестировать и переиспользовать.2️⃣ Связанность (Coupling)
Показывает, как одна сущность взаимодействует с другими. Класс А связан с классом Б, если в классе А
▫️Поля класса Б
▫️Вызов методов класса Б
▫️Локальные переменные класса Б
▫️Если класс А - подкласс Б
В большинстве проектов есть модуль base или common - часто он является примером сильной связанности. Менять такой модуль - всегда большой риск.
3️⃣ Сложность (Complexity)
На этот показатель влияет:
▪️Сколько сущностей взаимодействуют
▪️Количество операций в методе
▪️Глубина наследования
▪️Количество ветвлений и возможных состояний
Показатель сложности часто идёт рука об руку с размером, но не всегда. Сложный метод может быть небольшим по размеру, но скрывать внутри себя десятки вариантов развития событий:
public void check(long id) {
dao.get(id).findProcessor()
.getAccount().checkBalance();
}
4️⃣ Размер (Size)Большие сущности сложно поддерживать. В этой категории много метрик, например, количество:
🔹Полей
🔹Методов
🔹Статических методов
🔹Подклассов
🔹Связанных библиотек
А теперь ответы на вопросы перед постом:
✅ Если класс А часто использует класс Б, то это признак высокой связанности. Связанность (coupling) характеризует внешние отношения между сущностями. Связность (cohesion) - про внутреннюю структуру самой сущности.
✅ На сложность влияет количество ветвлений и глубина наследования. Остальные характеристики относятся к категории "размер".
👍3
Как на вашем проекте проверяется качество кода?
Anonymous Poll
24%
Checkstyle
5%
PMD
7%
FindBugs
1%
CodeMR
47%
Sonar
6%
Другие плагины IDE
4%
Другие внешние системы
43%
Только код-ревью🤗
Статический анализ кода, часть 2. Инструменты
В части 1 обсудили основные метрики: связность, связанность, сложность и размер. Также статический анализ включает проверку форматирования, поиск уязвимостей и возможных ошибок.
Когда и чем можно выполнять статистический анализ?
1️⃣ Во время написания кода.
С помощью встроенных правил IDE и дополнительных плагинов:
▫️Checkstyle проверяет форматирование, возможные ошибки, показывает сложные классы. Самый популярный плагин для Intellij IDEA.
▫️SonarLint и FindBugs ищут возможные ошибки, уязвимости, проверяют код на несколько тысяч ошибочных паттернов.
▫️CodeMR замеряет атрибуты качества кода — связность, сложность и т.д. Считает метрики, рисует картинки, показывает проблемные места с точки зрения дизайна.
▫️PMD ищет ошибочные паттерны в разных категориях — дизайн, кодстайл, производительность. Не знаю, почему этот плагин попадает во все списки анализаторов, у него достаточно скудный список правил по сравнению с аналогами.
2️⃣ Во время сборки.
Анализ редко делают в процессе сборки, но такая опция доступна — с помощью maven или gradle плагинов: Checkstyle Plugin, PMD Plugin.
3️⃣ На этапах CI/CD.
Можно запускать периодически или после определённых событий: создание пул-реквеста, слияние ветки. Результаты могут иметь рекомендательный характер, а могут не пропускать дальше по CI.
Конкретных инструментов много, как платных, так и бесплатных. Самый популярный - SonarQube. Метрики качества не считает, но проверяет на гигантское количество ошибочных паттернов и интегрируется с плагином в IDE.
JArchitect менее распространён и стоит дороже. Но и функций больше — метрики качества и красивые графики.
Статический анализ проводят в большинстве проектов. Обычно это проверка форматирования и поиск частых ошибок. Конкретные метрики считаются редко. И зря, ведь по ним можно объективно оценить:
🔸Текущее состояние кода
🔸Развитие системы от релиза к релизу
🔸Необходимость рефакторинга
🔸Проблемные места системы
В части 1 обсудили основные метрики: связность, связанность, сложность и размер. Также статический анализ включает проверку форматирования, поиск уязвимостей и возможных ошибок.
Когда и чем можно выполнять статистический анализ?
1️⃣ Во время написания кода.
С помощью встроенных правил IDE и дополнительных плагинов:
▫️Checkstyle проверяет форматирование, возможные ошибки, показывает сложные классы. Самый популярный плагин для Intellij IDEA.
▫️SonarLint и FindBugs ищут возможные ошибки, уязвимости, проверяют код на несколько тысяч ошибочных паттернов.
▫️CodeMR замеряет атрибуты качества кода — связность, сложность и т.д. Считает метрики, рисует картинки, показывает проблемные места с точки зрения дизайна.
▫️PMD ищет ошибочные паттерны в разных категориях — дизайн, кодстайл, производительность. Не знаю, почему этот плагин попадает во все списки анализаторов, у него достаточно скудный список правил по сравнению с аналогами.
2️⃣ Во время сборки.
Анализ редко делают в процессе сборки, но такая опция доступна — с помощью maven или gradle плагинов: Checkstyle Plugin, PMD Plugin.
3️⃣ На этапах CI/CD.
Можно запускать периодически или после определённых событий: создание пул-реквеста, слияние ветки. Результаты могут иметь рекомендательный характер, а могут не пропускать дальше по CI.
Конкретных инструментов много, как платных, так и бесплатных. Самый популярный - SonarQube. Метрики качества не считает, но проверяет на гигантское количество ошибочных паттернов и интегрируется с плагином в IDE.
JArchitect менее распространён и стоит дороже. Но и функций больше — метрики качества и красивые графики.
Статический анализ проводят в большинстве проектов. Обычно это проверка форматирования и поиск частых ошибок. Конкретные метрики считаются редко. И зря, ведь по ним можно объективно оценить:
🔸Текущее состояние кода
🔸Развитие системы от релиза к релизу
🔸Необходимость рефакторинга
🔸Проблемные места системы
❤1
Тестирование, часть 1. Вопросы на собеседовании
Чем опытней разработчик, тем больше тем обсуждается на собеседованиях. Начиная с уровня middle будьте готовы к таким вопросам:
1️⃣ Назовите свойства юнит-тестов?
Хорошие юнит-тесты соблюдают принцип FIRST:
🔸F – Fast
Выполняются быстро. Никто не хочет лишний раз запускать медленные тесты. Один юнит-тест — не дольше 0.5 сек.
🔸I – Isolated / Independent
Любой набор тестов можно запускать в любом порядке, тесты не зависят друг на друга. Каждый тест сфокусирован на одном действии и наборе параметров. Если тест упал, то сразу понятно, где и при каких условиях возникла ошибка.
🔸R – Repeatable
Результат теста не зависит от операционной системы, конфигурации компьютера, внешних ресурсов и наличия интернета. Результат теста повторяется при многократном вызове.
⭐️ Это свойство хромает, когда тесты используют случайные числа или проверяют работу нескольких потоков.
🔸S – Self-Validating
У теста два результата — прошёл или нет. Разработчик не должен проверять записи в логе или сравнивать текстовые файлы.
🔸T - Timely
Тесты пишутся вовремя, в рамках той же задачи, что и основной код.
⭐️ Юнит-тесты должны быть читаемыми. Тогда их легко поменять, если бизнес-логика изменится. Сложно разбираться в методах test1(), test2(), test3() и переменных a, b, c.
⭐️ По тестам можно оценить инженерную культуру компании. Обратите внимание на количество и качество юнит-тестов, кто и когда их пишет. Если тестов нет, или сеньор пишет код и создаёт подзадачу «написать тесты» для джуниора - это дно. Откладывать тесты из-за дедлайна — тоже так себе.
⭐️ Тесты можно не писать для PoC (proof of concept) — временный код для проверки гипотез, который не связан с продакшн кодом.
Тесты организуют по структуре 3A (Arrange-Act-Assert), также встречается название Given-When-Then.
3 блока должны чётко следовать друг за другом, тогда тест легко читать. Если после блока проверок идёт действие и дополнительные проверки — значит тест слишком большой.
2️⃣ Что такое TDD?
Test Driven Development - процесс разработки, когда сначала пишется тест, а потом код. Подробно это выглядит так:
▫️Написать тест для кода, которого нет
▫️Запустить тесты, новый тест падает
▫️Написать код, чтобы тест проходил
▫️Запустить тесты, тесты проходят
▫️Рефакторинг нового кода
▫️Запустить тесты, тесты проходят
Плюсы TDD:
➕Код сразу покрыт тестами
➕У класса удобный интерфейс, который сразу используется в тестах
➕Структурированный код
После этого следует такой диалог:
- А Вы лично используете TDD?
- Нет.
- Почему? У него же столько плюсов.
- Большой минус - частое переключение контекста и фокус на деталях. Мне удобнее написать простое рабочее решение, и только потом добавить проверки, валидацию и обработку ошибок. После этого в соответствии с требованиями как следует оттестировать то, что получилось. Я сразу пишу код, который легко использовать и тестировать, поэтому TDD меня только замедляет.
- Согласен.
Чем опытней разработчик, тем больше тем обсуждается на собеседованиях. Начиная с уровня middle будьте готовы к таким вопросам:
1️⃣ Назовите свойства юнит-тестов?
Хорошие юнит-тесты соблюдают принцип FIRST:
🔸F – Fast
Выполняются быстро. Никто не хочет лишний раз запускать медленные тесты. Один юнит-тест — не дольше 0.5 сек.
🔸I – Isolated / Independent
Любой набор тестов можно запускать в любом порядке, тесты не зависят друг на друга. Каждый тест сфокусирован на одном действии и наборе параметров. Если тест упал, то сразу понятно, где и при каких условиях возникла ошибка.
🔸R – Repeatable
Результат теста не зависит от операционной системы, конфигурации компьютера, внешних ресурсов и наличия интернета. Результат теста повторяется при многократном вызове.
⭐️ Это свойство хромает, когда тесты используют случайные числа или проверяют работу нескольких потоков.
🔸S – Self-Validating
У теста два результата — прошёл или нет. Разработчик не должен проверять записи в логе или сравнивать текстовые файлы.
🔸T - Timely
Тесты пишутся вовремя, в рамках той же задачи, что и основной код.
⭐️ Юнит-тесты должны быть читаемыми. Тогда их легко поменять, если бизнес-логика изменится. Сложно разбираться в методах test1(), test2(), test3() и переменных a, b, c.
⭐️ По тестам можно оценить инженерную культуру компании. Обратите внимание на количество и качество юнит-тестов, кто и когда их пишет. Если тестов нет, или сеньор пишет код и создаёт подзадачу «написать тесты» для джуниора - это дно. Откладывать тесты из-за дедлайна — тоже так себе.
⭐️ Тесты можно не писать для PoC (proof of concept) — временный код для проверки гипотез, который не связан с продакшн кодом.
Тесты организуют по структуре 3A (Arrange-Act-Assert), также встречается название Given-When-Then.
// givenИнициализация переменных и моков.
// whenВызов проверяемого метода.
// thenПроверка результата и состояния других объектов.
3 блока должны чётко следовать друг за другом, тогда тест легко читать. Если после блока проверок идёт действие и дополнительные проверки — значит тест слишком большой.
2️⃣ Что такое TDD?
Test Driven Development - процесс разработки, когда сначала пишется тест, а потом код. Подробно это выглядит так:
▫️Написать тест для кода, которого нет
▫️Запустить тесты, новый тест падает
▫️Написать код, чтобы тест проходил
▫️Запустить тесты, тесты проходят
▫️Рефакторинг нового кода
▫️Запустить тесты, тесты проходят
Плюсы TDD:
➕Код сразу покрыт тестами
➕У класса удобный интерфейс, который сразу используется в тестах
➕Структурированный код
После этого следует такой диалог:
- А Вы лично используете TDD?
- Нет.
- Почему? У него же столько плюсов.
- Большой минус - частое переключение контекста и фокус на деталях. Мне удобнее написать простое рабочее решение, и только потом добавить проверки, валидацию и обработку ошибок. После этого в соответствии с требованиями как следует оттестировать то, что получилось. Я сразу пишу код, который легко использовать и тестировать, поэтому TDD меня только замедляет.
- Согласен.
❤3👍2
Тестирование, часть 2. Тестовое покрытие
Code coverage (CC) - метрика, которая показывает, насколько код покрыт тестами.
❓Как считается СС?
Запускаются тесты и отслеживается, какие классы, методы и строки кода выполнились. Это число делится на общее количество и так получается процент кода, покрытый тестами.
❓Почему у СС плохая репутация?
❌ Не говорит о качестве тестирования и надёжности системы. Если метод выполнился, это не значит, что он протестирован.
❌ Тестировать get/set методы, конструкторы и классы-конфиги нет необходимости, но из-за жёстких требований по СС приходится писать бесполезные тесты.
❓Зачем считать СС?
✅ Менеджеры хотят быть в курсе состояния проекта и не хотят смотреть в код. Поэтому их главный инструмент - это метрики, в том числе СС. Так оценивается текущая ситуация и сравниваются релизы.
✅ Качество и надёжность— понятия субъективные. С помощью СС и последующего анализа можно найти компоненты, которые слабо покрыты тестами. Таким образом увеличить надёжность системы.
❓Какие значения СС нормальные?
Для большинства проектов это 60-80%.
❓Как посчитать?
1️⃣ Intellij IDEA:
Run → Run with Coverage
По умолчанию IDEA использует свой способ подсчёта, но для java есть ещё 2 библиотеки:
🔸JaCoCo
🔸Emma (не поддерживается с 2013)
Результаты разных библиотек могут отличаться. Если на этапе CI/CD используется JaCoCo, то лучше в IDE тоже использовать JaCoCo. Чтобы поменять:
Run → Edit Configurations... → Code Coverage → Choose coverage runner
2️⃣ Во время сборки.
Те же библиотеки используются в Maven и Gradle плагинах — JaCoCo Plugin, Emma Plugin.
3️⃣ На этапах CI/CD.
JaCoCo Plugin и Emma Plugin доступны для Jenkins, Teamcity, GitLab, Travis и остальных CI серверов.
Code coverage (CC) - метрика, которая показывает, насколько код покрыт тестами.
❓Как считается СС?
Запускаются тесты и отслеживается, какие классы, методы и строки кода выполнились. Это число делится на общее количество и так получается процент кода, покрытый тестами.
❓Почему у СС плохая репутация?
❌ Не говорит о качестве тестирования и надёжности системы. Если метод выполнился, это не значит, что он протестирован.
❌ Тестировать get/set методы, конструкторы и классы-конфиги нет необходимости, но из-за жёстких требований по СС приходится писать бесполезные тесты.
❓Зачем считать СС?
✅ Менеджеры хотят быть в курсе состояния проекта и не хотят смотреть в код. Поэтому их главный инструмент - это метрики, в том числе СС. Так оценивается текущая ситуация и сравниваются релизы.
✅ Качество и надёжность— понятия субъективные. С помощью СС и последующего анализа можно найти компоненты, которые слабо покрыты тестами. Таким образом увеличить надёжность системы.
❓Какие значения СС нормальные?
Для большинства проектов это 60-80%.
❓Как посчитать?
1️⃣ Intellij IDEA:
Run → Run with Coverage
По умолчанию IDEA использует свой способ подсчёта, но для java есть ещё 2 библиотеки:
🔸JaCoCo
🔸Emma (не поддерживается с 2013)
Результаты разных библиотек могут отличаться. Если на этапе CI/CD используется JaCoCo, то лучше в IDE тоже использовать JaCoCo. Чтобы поменять:
Run → Edit Configurations... → Code Coverage → Choose coverage runner
2️⃣ Во время сборки.
Те же библиотеки используются в Maven и Gradle плагинах — JaCoCo Plugin, Emma Plugin.
3️⃣ На этапах CI/CD.
JaCoCo Plugin и Emma Plugin доступны для Jenkins, Teamcity, GitLab, Travis и остальных CI серверов.
❤3👍1
Статистика: что использовали Java разработчики в 2019 году
Бостонская компания Snyk каждый год опрашивает разработчиков об их проектах и технологиях. В прошлом году в опросе поучаствовало две тысячи человек, в том числе 8% участников из России.
Главное из отчёта за 2019:
1️⃣ Какая версия java используется в продакшене?
64% — 8
25% — 11
3% — 7 и ниже
2️⃣ Почему Вы не переходите на последнюю версию java?
51% — И так всё устраивает
32% — Трудности с миграцией
30% — Сложно согласовать переход
3️⃣ Какой JVM язык используется в качестве основного?
87% — Java
5,5% — Kotlin
2,9% — Closure
2,6% — Scala
1,5% — Groovy
4️⃣ Вы используете разбиение на модули (фича Java 9)?
64% — Нет
29% — Планируем
7% — Да
5️⃣ Какая у Вас версия Spring в продакшене?
48% — 5.1
18% — 5.0
17% — 4.3
5% — 4.2
4% — 3.2
6️⃣ Какой серверный веб-фреймворк Вы используете?
50% — Spring Boot
31% — Spring MVC
11% — JSF
5% — Vert.x
5% — Vaadin
5% — Struts
7️⃣ Ваша основная IDE:
62% — Intellij IDEA
20% — Eclipse
10% — NetBeans
8️⃣ Ваш инструмент сборки:
64% — Maven
25% — Gradle
6% — Ant
9️⃣ Ваш CI-сервер:
58% — Jenkins
12% — Никакой
6% — GitLab
5% — TeamCity
4% — Bamboo
4% — Travis
4%— Circle
🔟 Ваш репозиторий:
24% — private GitLab
16% — public GitHub
15% — Enterprise GitHub
15% — BitBucket Server
11% — public GitLab
10% — BitBucket Cloud
Полная версия отчёта тут. Очень удивило, что 12% не используют CI, и что Closure обогнал Scala. Рост популярности Intellij IDEA по сравнению с прошлым годом тоже впечатляет:
Бостонская компания Snyk каждый год опрашивает разработчиков об их проектах и технологиях. В прошлом году в опросе поучаствовало две тысячи человек, в том числе 8% участников из России.
Главное из отчёта за 2019:
1️⃣ Какая версия java используется в продакшене?
64% — 8
25% — 11
3% — 7 и ниже
2️⃣ Почему Вы не переходите на последнюю версию java?
51% — И так всё устраивает
32% — Трудности с миграцией
30% — Сложно согласовать переход
3️⃣ Какой JVM язык используется в качестве основного?
87% — Java
5,5% — Kotlin
2,9% — Closure
2,6% — Scala
1,5% — Groovy
4️⃣ Вы используете разбиение на модули (фича Java 9)?
64% — Нет
29% — Планируем
7% — Да
5️⃣ Какая у Вас версия Spring в продакшене?
48% — 5.1
18% — 5.0
17% — 4.3
5% — 4.2
4% — 3.2
6️⃣ Какой серверный веб-фреймворк Вы используете?
50% — Spring Boot
31% — Spring MVC
11% — JSF
5% — Vert.x
5% — Vaadin
5% — Struts
7️⃣ Ваша основная IDE:
62% — Intellij IDEA
20% — Eclipse
10% — NetBeans
8️⃣ Ваш инструмент сборки:
64% — Maven
25% — Gradle
6% — Ant
9️⃣ Ваш CI-сервер:
58% — Jenkins
12% — Никакой
6% — GitLab
5% — TeamCity
4% — Bamboo
4% — Travis
4%— Circle
🔟 Ваш репозиторий:
24% — private GitLab
16% — public GitHub
15% — Enterprise GitHub
15% — BitBucket Server
11% — public GitLab
10% — BitBucket Cloud
Полная версия отчёта тут. Очень удивило, что 12% не используют CI, и что Closure обогнал Scala. Рост популярности Intellij IDEA по сравнению с прошлым годом тоже впечатляет:
❤1
Сколько часов в день Вы пишете код?
Anonymous Poll
20%
Меньше часа
31%
1-3 часа
27%
3-5 часов
16%
5-8 часов
6%
Больше 8 часов
WakaTime: лёгкий способ прокачать навык эстимации
Секрет успеха прост — составить план и придерживаться его. Задача разработчика при планировании - оценить время на задачу с учётом сложности и рисков. Точные прогнозы это плюс к репутации, сорванные сроки — минус.
Навык оценки легко тренировать - почаще сравнивать оценку и фактическое время выполнения. Со временем у вас разовьётся сильная интуиция и адекватная оценка своих способностей. Приятный бонус - любовь менеджеров и низкий уровень стресса😌
Самое сложное — посчитать, сколько времени по факту ушло на задачу. Можно полагаться на память, а можно трекать время автоматически. Самый популярный плагин Intellij IDEA для Git — WakaTime. В бесплатной версии недоступно почти всё, но можно смотреть:
🔸Сколько времени ушло на написание кода
🔸Сколько времени заняла каждая задача:
Полная инструкция:
1️⃣ Установить в IDEA плагин WakaTime
2️⃣ Перезапустить IDEA, появится окошко для ключа
3️⃣ Зарегистрироваться на сайте и перейти в раздел для IDEA
4️⃣ Взять из п.5 API Key, ввести его в IDE
5️⃣ Зайти в настройки, отключить все уведомления
6️⃣ Зайти в дашборд
Можно трекать работу в других IDE и редакторах — Eclipse, Android Studio, GoLand, даже в Notepad++. Можно подключить к GitLab, GitHub и BitBucket и смотреть, сколько времени занял каждый коммит.
Секрет успеха прост — составить план и придерживаться его. Задача разработчика при планировании - оценить время на задачу с учётом сложности и рисков. Точные прогнозы это плюс к репутации, сорванные сроки — минус.
Навык оценки легко тренировать - почаще сравнивать оценку и фактическое время выполнения. Со временем у вас разовьётся сильная интуиция и адекватная оценка своих способностей. Приятный бонус - любовь менеджеров и низкий уровень стресса😌
Самое сложное — посчитать, сколько времени по факту ушло на задачу. Можно полагаться на память, а можно трекать время автоматически. Самый популярный плагин Intellij IDEA для Git — WakaTime. В бесплатной версии недоступно почти всё, но можно смотреть:
🔸Сколько времени ушло на написание кода
🔸Сколько времени заняла каждая задача:
5h 6 mins feature/EX-45Для мониторинга своей активности этого достаточно.
50 mins bugfix/EX-64
Полная инструкция:
1️⃣ Установить в IDEA плагин WakaTime
2️⃣ Перезапустить IDEA, появится окошко для ключа
3️⃣ Зарегистрироваться на сайте и перейти в раздел для IDEA
4️⃣ Взять из п.5 API Key, ввести его в IDE
5️⃣ Зайти в настройки, отключить все уведомления
6️⃣ Зайти в дашборд
Можно трекать работу в других IDE и редакторах — Eclipse, Android Studio, GoLand, даже в Notepad++. Можно подключить к GitLab, GitHub и BitBucket и смотреть, сколько времени занял каждый коммит.
❤1
Привет!
Сегодня будет не полезный пост, а небольшая просьба. Я пишу посты в этом канале уже 5 месяцев: делюсь знаниями, инструментами и аналитикой, стараюсь доступно передать свой 7-летний опыт java разработки.
Постоянная обратная связь мотивирует писать дальше: меня очень радуют ваши лайки, шеры и личные сообщения. Приятно, что вы цените точную и практическую информацию и мой труд🧡
Я уже несколько месяцев занимаюсь созданием курса по многопоточности в java. В нём будет:
▫️Необходимая теоретическая часть
▫️Как и какими инструментами решать конкретные задачи
▫️Что актуально сейчас и тренды ближайших лет
▫️Разбор вопросов с собеседований
Большая часть материалов готова, но я хочу убедиться, что раскрыла все важные и интересные темы. Поэтому прошу вас мне помочь и заполнить небольшую анкету:
https://docs.google.com/forms/d/10zfRjnM6Fbpr03LWbNRETQDl3SNd7kjGmVh7Rh2XFRY/edit?usp=sharing
Сегодня будет не полезный пост, а небольшая просьба. Я пишу посты в этом канале уже 5 месяцев: делюсь знаниями, инструментами и аналитикой, стараюсь доступно передать свой 7-летний опыт java разработки.
Постоянная обратная связь мотивирует писать дальше: меня очень радуют ваши лайки, шеры и личные сообщения. Приятно, что вы цените точную и практическую информацию и мой труд🧡
Я уже несколько месяцев занимаюсь созданием курса по многопоточности в java. В нём будет:
▫️Необходимая теоретическая часть
▫️Как и какими инструментами решать конкретные задачи
▫️Что актуально сейчас и тренды ближайших лет
▫️Разбор вопросов с собеседований
Большая часть материалов готова, но я хочу убедиться, что раскрыла все важные и интересные темы. Поэтому прошу вас мне помочь и заполнить небольшую анкету:
https://docs.google.com/forms/d/10zfRjnM6Fbpr03LWbNRETQDl3SNd7kjGmVh7Rh2XFRY/edit?usp=sharing
❤1
Ребята, спасибо, что уделили время заполнению анкеты! Я получила больше сотни ответов и ценных идей, буду внедрять💪
Многие писали, что присоединились недавно, поэтому на этой неделе будут подборки самых популярных статей. Если что-то пропустили — рекомендую прочесть.
Многие писали, что присоединились недавно, поэтому на этой неделе будут подборки самых популярных статей. Если что-то пропустили — рекомендую прочесть.
Подборка: подготовка к собеседованиям
🔥Рейтинг технологий в вакансиях HeadHunter🔥
Вопросы с собеседований:
▫️Сравнение переменных
▫️Как создать поток: 7 вариантов ответа
▫️Интерфейсы: поля и методы
▫️Интерфейсы: отличия от абстрактного класса
▫️Вопросы про юнит-тесты
🔥Рейтинг технологий в вакансиях HeadHunter🔥
Вопросы с собеседований:
▫️Сравнение переменных
▫️Как создать поток: 7 вариантов ответа
▫️Интерфейсы: поля и методы
▫️Интерфейсы: отличия от абстрактного класса
▫️Вопросы про юнит-тесты
Подборка: Java core и Java 8
⚙️Java core:
▫️Сборщики мусора. Плюсы и минусы G1
▫️Как работает переопределение методов?
▫️2 способа обхода коллекций
▫️Система типов и проверка аргументов
👑 Java 8:
▪️Stream API: обзор и основные методы
▪️Stream API: ускоряемся🚀
▪️HashMap в Java 8
▪️Функциональные интерфейсы: обзор
▪️Функциональные интерфейсы: best practices
⚙️Java core:
▫️Сборщики мусора. Плюсы и минусы G1
▫️Как работает переопределение методов?
▫️2 способа обхода коллекций
▫️Система типов и проверка аргументов
👑 Java 8:
▪️Stream API: обзор и основные методы
▪️Stream API: ускоряемся🚀
▪️HashMap в Java 8
▪️Функциональные интерфейсы: обзор
▪️Функциональные интерфейсы: best practices
Как JVM работает со строками, часть 1
По статистике OpenJDK в приложениях 15-50% памяти занимают экземпляры String. Это много, поэтому разработчики JVM прикладывают много усилий, чтобы оптимизировать работу со строками.
❓Как сэкономить память, если в системе миллионы экземпляров?
1️⃣ Уменьшить количество памяти под одну строку.
Мы уже разбирали этот случай: в java 9 вышло обновление Compact String и размер памяти под строки сократился до 2 раз.
2️⃣ Добавить кэширование.
Есть два способа создать экземпляр String:
🔸Через оператор new:
🔸Без оператора new:
▫️Проверить в String Pool, есть ли там такая строка.
▫️Если есть — вернуть её.
▫️Если нет — создать объект, поместить в кэш, вернуть.
❓Как реализован String pool?
Структура похожа на HashMap: хэш-таблица фиксированного размера с парами хэш — строка. В последних версиях java она занимает 64 МБ, при желании размер меняется с помощью флажка:
✅ Ответ на 1 вопрос перед постом:
Можно исправить ситуацию и добавить строчку в кэш методом intern():
Но если строка "Java" использовалась раньше и попала в кэш, то будет создана только одна строка — new String.
По статистике OpenJDK в приложениях 15-50% памяти занимают экземпляры String. Это много, поэтому разработчики JVM прикладывают много усилий, чтобы оптимизировать работу со строками.
❓Как сэкономить память, если в системе миллионы экземпляров?
1️⃣ Уменьшить количество памяти под одну строку.
Мы уже разбирали этот случай: в java 9 вышло обновление Compact String и размер памяти под строки сократился до 2 раз.
2️⃣ Добавить кэширование.
Есть два способа создать экземпляр String:
🔸Через оператор new:
String s = new String ("one");
В памяти создаётся новый объект.🔸Без оператора new:
String s = "one";В этом случае идёт работа с кэшем строк под названием String pool. Схема работы такая:
▫️Проверить в String Pool, есть ли там такая строка.
▫️Если есть — вернуть её.
▫️Если нет — создать объект, поместить в кэш, вернуть.
❓Как реализован String pool?
Структура похожа на HashMap: хэш-таблица фиксированного размера с парами хэш — строка. В последних версиях java она занимает 64 МБ, при желании размер меняется с помощью флажка:
-XX:StringTableSize=65536В следующем посте рассмотрим ещё два способа снижения издержек на строки.
✅ Ответ на 1 вопрос перед постом:
new String("Java") создаёт новый объект в хипе, s2 = "Java" создаёт объект в String pool. Это два разных объекта, поэтому при сравнении через == результат будет false.Можно исправить ситуацию и добавить строчку в кэш методом intern():
String s1="Java";✅Рассмотрим второй вопрос. О том, сколько строк создаётся в конструкции
String s2=new String("Java");
s2=s2.intern();
println(s1==s2); //true
String str=new String("Java");
Подвох в том, что для конструктора String нужен экземпляр String, поэтому создаётся 2 строки — "Java" и new String;Но если строка "Java" использовалась раньше и попала в кэш, то будет создана только одна строка — new String.
❤1
Какой GoF паттерн реализует String pool?
Anonymous Quiz
24%
Заместитель (Proxy)
28%
Приспособленец (Flyweight)
28%
Компоновщик (Composite)
20%
Посредник (Mediator)
👍1
А вот и второй вопрос, он должен был быть перед постом🤫
Сколько экземпляров String создаётся в этой строке кода:
Сколько экземпляров String создаётся в этой строке кода:
Как JVM работает со строками, часть 2
Ссылка на часть 1.
Сегодня рассмотрим ещё 2 простых, но эффективных приёма JVM по оптимизации строк.
Оба связаны со внутренним устройством String:
При использовании оператора new в памяти создаётся новый объект:
❓Почему заменяется только текст, а не вся строка?
Ссылки на строчку могут быть в десятках мест. Текст — внутреннее поле, его заменить гораздо проще
❓Почему совместим только с G1?
Нашла только один комментарий по теме: G1 – единственный сборщик мусора, в котором есть pinned regions. Это области, в которых не происходит дефрагментация. Но почему нельзя разместить хэш-таблицу в другом месте — непонятно😕
❓Почему опция по умолчанию не работает?
Deduplication хорошо экономит память, когда в программе через оператор new создаётся много похожих строк-долгожителей. Тогда экономится больше памяти, чем затраты на копирование в хэш-таблицу. По статистике OpenJDK таких случаев мало, поэтому StringDeduplication по умолчанию отключен.
Для активации добавьте при запуске VM флажок:
Хэшкод строки играет важную роль в хэш-таблицах String pool, Deduplication и других процессах JVM.
Внутри класса String хэш хранится как примитив:
Если хэш равен 0, то он пересчитывается каждый раз. Шанс этого очень низкий, но в Java 13 в String добавился флаг для нулевого хэша:
Итого: оптимизацией строк идёт по всем фронтам:
1️⃣ Структура данных (Java 9: Compact Strings)
2️⃣ Кэширование (String pool)
3️⃣ Оптимизация частных случаев (Java 8: String Deduplication)
4️⃣ Микрооптимизации (Java 13: флажок hashIsZero)
Ссылка на часть 1.
Сегодня рассмотрим ещё 2 простых, но эффективных приёма JVM по оптимизации строк.
Оба связаны со внутренним устройством String:
byte[] value — текстbyte coder — тип кодировкиint hash1️⃣ String Deduplication (Java 8)
При использовании оператора new в памяти создаётся новый объект:
String str = new String("12");
Отдельный JVM поток ищет в памяти экземпляры String и записывает их текст в хэш-таблицу:hash → byte[]Если поток находит дубликат, то заменяет ссылку в повторяющейся строке на ссылку из хэш-таблицы:
str.value = hashtable.valueНа текст дубликата больше нет ссылок, поэтому он удалится сборщиком мусора. Так можно сэкономить 5-30% памяти. Опция String Deduplication работает только со сборщиком G1, и по умолчанию отключена.
❓Почему заменяется только текст, а не вся строка?
Ссылки на строчку могут быть в десятках мест. Текст — внутреннее поле, его заменить гораздо проще
❓Почему совместим только с G1?
Нашла только один комментарий по теме: G1 – единственный сборщик мусора, в котором есть pinned regions. Это области, в которых не происходит дефрагментация. Но почему нельзя разместить хэш-таблицу в другом месте — непонятно😕
❓Почему опция по умолчанию не работает?
Deduplication хорошо экономит память, когда в программе через оператор new создаётся много похожих строк-долгожителей. Тогда экономится больше памяти, чем затраты на копирование в хэш-таблицу. По статистике OpenJDK таких случаев мало, поэтому StringDeduplication по умолчанию отключен.
Для активации добавьте при запуске VM флажок:
-XX:+UseStringDeduplicationЧтобы посмотреть, сколько памяти сэкономил Deduplication, можно вывести статистику Xlog:
-Xlog:stringdedup*=debug2️⃣ Оптимизация хэш-кода (Java 13)
Хэшкод строки играет важную роль в хэш-таблицах String pool, Deduplication и других процессах JVM.
Внутри класса String хэш хранится как примитив:
int hashВычисляется и сохраняется при первом вызове hashcode():
if (hash == 0) {
hash = ...
}
⛔️Минус такого решения:Если хэш равен 0, то он пересчитывается каждый раз. Шанс этого очень низкий, но в Java 13 в String добавился флаг для нулевого хэша:
boolean hashIsZeroПроверка того, что хэш-код ещё не посчитан, стала такой:
if (h == 0 && !hashIsZero)Теперь хэш-код всегда считается один раз.
Итого: оптимизацией строк идёт по всем фронтам:
1️⃣ Структура данных (Java 9: Compact Strings)
2️⃣ Кэширование (String pool)
3️⃣ Оптимизация частных случаев (Java 8: String Deduplication)
4️⃣ Микрооптимизации (Java 13: флажок hashIsZero)
👍3
Intellij IDEA: Memory view
❓Как в IDEA посмотреть количество объектов в памяти?
По умолчанию подсчёт объектов при дебаге выключен, потому что это тяжелая операция и сильно тормозит процесс отладки.
Чтобы включить:
1️⃣ В окне Debug найдите вкладку Memory View.
2️⃣ Нажмите на шестерёнку в Memory View и выберите
✅ Update Loaded Classes On Debugger Stop
Картинка с инструкцией внизу⬇️
Что показывает:
🔸Count - количество экземпляров
🔸Diff - изменения с прошлого шага
При каждой остановке информация о количестве объектов обновляется.
Так можно наглядно посмотреть на работу String pool. Помните, был вопрос:
Сколько строк создаётся в конструкции:
Поменяем код на
❓Как в IDEA посмотреть количество объектов в памяти?
По умолчанию подсчёт объектов при дебаге выключен, потому что это тяжелая операция и сильно тормозит процесс отладки.
Чтобы включить:
1️⃣ В окне Debug найдите вкладку Memory View.
2️⃣ Нажмите на шестерёнку в Memory View и выберите
✅ Update Loaded Classes On Debugger Stop
Картинка с инструкцией внизу⬇️
Что показывает:
🔸Count - количество экземпляров
🔸Diff - изменения с прошлого шага
При каждой остановке информация о количестве объектов обновляется.
Так можно наглядно посмотреть на работу String pool. Помните, был вопрос:
Сколько строк создаётся в конструкции:
String s = new String("Java");
Откроем Memory View. После выполнения строки напротив класса java.lang.String увидим Diff +2.Поменяем код на
String java = "Java";Запустим снова. "Java" в первой строке отправилась в String pool. Теперь после выполнения второй строки напротив java.lang.String будет Diff +1.
String s = new String("Java");
❤1