Java for Beginner
717 subscribers
660 photos
174 videos
12 files
1.03K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
4.2. Избегайте лишних условий
Не проверяйте условия, которые можно упростить или убрать.

Пример:
// Плохо: избыточное условие
if (isActive == true) {
System.out.println("Активен!");
}

// Хорошо: упрощение
if (isActive) {
System.out.println("Активен!");
}



4.3. Используйте else if для взаимоисключающих условий

Если условия взаимосвязаны, используйте else if, чтобы не проверять лишние условия.

Пример:
int x = 5;
if (x > 0) {
System.out.println("Положительное");
} else if (x < 0) {
System.out.println("Отрицательное");
} else {
System.out.println("Ноль");
}


4.4. Избегайте глубоких вложений
Слишком много вложенных if делают код сложным для чтения. Используйте переменные или методы для упрощения.

Пример:
// Плохо: глубокая вложенность
if (age >= 18) {
if (hasTicket) {
if (isVenueOpen) {
System.out.println("Вход разрешен!");
}
}
}

// Хорошо: упрощение
boolean canEnter = age >= 18 && hasTicket && isVenueOpen;
if (canEnter) {
System.out.println("Вход разрешен!");
}


4.5. Проверяйте на null
При работе с объектами всегда проверяйте на null, чтобы избежать NullPointerException.

Пример:
String name = null;
if (name != null) {
System.out.println("Имя: " + name);
} else {
System.out.println("Имя не задано!");
}



5. Назначение if / else

if и else выполняют важные функции в программировании:

5.1. Управление потоком
Позволяют программе выбирать, какой код выполнять, в зависимости от условий.

5.2. Обработка разных случаев
Помогают обрабатывать разные сценарии, например, успех или ошибку.


5.3. Улучшение читаемости
Делают логику программы понятной, показывая, как данные влияют на поведение.

5.4. Гибкость
Позволяют писать код, который адаптируется к разным входным данным.


6. Работа if / else под капотом

Понимание, как if и else работают в JVM, поможет писать более эффективный код.

6.1. Компиляция в байт-код

Компилятор Java (javac) переводит if и else в инструкции условного перехода в байт-коде.
Условие в if преобразуется в сравнение (например, if_icmpgt для сравнения чисел), а затем JVM решает, какой блок кода выполнить.


Пример:
int x = 5;
if (x > 0) {
System.out.println("Положительное");
}


Байт-код (упрощенно):

iload x        // Загружаем x в стек
ifgt label // Если x > 0, перейти к метке
return // Иначе выйти
label:
invokevirtual // Вызов System.out.println
return


6.2. Память и стек
Стек операндов: Условие if вычисляется в стеке операндов JVM. Например, для x > 0 JVM загружает x и 0, сравнивает их и сохраняет результат (true или false).
Локальные переменные: Переменные, используемые в условии (например, x), хранятся в стеке вызовов.
Куча: Если в условии используются объекты (например, name != null), они находятся в куче, а их ссылки — в стеке.


6.3. Оптимизация в JVM

JIT-компиляция: JIT-компилятор может оптимизировать if/else, встраивая часто используемые условия в машинный код.
Короткое замыкание: Если условие в if использует логические операторы (&&, ||), JVM пропускает ненужные вычисления.
Константные условия: Если условие всегда true или false (например, if (true)), компилятор может убрать ненужный код.


Пример оптимизации:
if (false) {
System.out.println("Никогда не выполнится");
}

Компилятор полностью удалит этот блок из байт-кода.


6.4. Ошибки в памяти
Глубокие вложенности: Слишком много вложенных if увеличивают глубину стека вызовов, но это редко вызывает проблемы.
NullPointerException: Работа с объектами без проверки на null в условии может привести к ошибке.
Неэффективные условия: Сложные условия, такие как a > b && b > c && c > d, могут замедлить выполнение, если не оптимизированы.


Пример ошибки:
String text = null;
if (text.equals("Hello")) { // Ошибка: NullPointerException
System.out.println("Совпадение!");
}

Исправление:
if (text != null && text.equals("Hello")) {
System.out.println("Совпадение!");
}


#Java #для_новичков #beginner #if #else
👍3
Что выведет код?

public class Task050825 {
public static void main(String[] args) {
int x = 5;

if (x > 10)
if (x < 20)
System.out.println("A");
else
System.out.println("B");
else if (x > 2)
if (x < 8)
System.out.println("C");
else
System.out.println("D");
else
System.out.println("E");
}
}


#Tasks
🗿5👍3
Варианты ответа:
Anonymous Quiz
14%
A
6%
B
61%
C
19%
D
👍3🗿3
Карточка для запоминания float 😎

#memory_card
👍5
Что такое finalizer в Java и почему его не рекомендуется использовать? 🤓

Ответ:

Метод finalize() в классе Object вызывается сборщиком мусора перед удалением объекта, но его использование не рекомендуется. Он ненадежен, так как GC не гарантирует вызов, и может замедлить работу.

Пример:
class Resource {
@Override
protected void finalize() throws Throwable {
System.out.println("Cleaning up");
}
}

Вместо finalize() лучше использовать try-with-resources или AutoCloseable для явного управления ресурсами.

С Java 9 finalize() помечен как устаревший.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
📌 Факт дня:

А вы знали, что одна из первых систем для обучения через компьютеры, была создана в 1960 году?

Основываясь на теории программированного обучения, в 1960 году 26-летний инженер Дональд Битцер (Donald Bitzer), только что получивший степень в университете Иллинойса, разработал компьютерную систему PLATO (Programmed Logic for Automated Teaching Operations).

Терминалы PLATO подключались к университетскому мейнфрейму ILLIAC I. Дисплеем для них служил обычный телевизор, а на клавиатуре пользователя имелось всего 16 клавиш для навигации. Студенты университета могли изучать несколько тематических курсов.


proof

#facts
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
ℹ️ Кто родился в этот день

Трэ́вис Корделл Ка́ланик (англ. Travis Cordell Kalanick, родился 6 августа 1976) — американский предприниматель, сооснователь и бывший CEO компании Uber (технологического сервиса для заказа такси).

Ке́вин Дэ́вид Ми́тник (англ. Kevin David Mitnick; 6 августа 1963, Лос-Анджелес, Калифорния, США — 16 июля 2023, Лас-Вегас) — американский программист, в прошлом известный хакер, впоследствии специалист по компьютерной безопасности

#Biography #Birth_Date
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Конфигурация, профили, параметры и свойства в Gradle: Управление сборкой

Системные свойства, переменные окружения

Gradle поддерживает настройку через системные свойства и переменные окружения, которые задают параметры JVM и сборки.

Системные свойства:
Задаются через -D в командной строке или в gradle.properties.

Пример:
./gradlew build -Dorg.gradle.jvmargs=-Xmx2048m


Доступ в build.gradle:
println System.getProperty('org.gradle.jvmargs')



Переменные окружения:
Доступны через System.getenv().

Пример:
println System.getenv('JAVA_HOME')


Полезны для передачи внешних параметров (например, API-ключи, пути).

Приоритет:
Системные свойства (-D) > gradle.properties > переменные окружения.
В памяти: Системные свойства и переменные окружения загружаются как часть конфигурации JVM, добавляя минимальный overhead (менее 10 МБ). Gradle кэширует их значения в модели проекта.


Нюансы:
Используйте переменные окружения для чувствительных данных с осторожностью, предпочтительно шифруйте их.

Проверяйте наличие переменных:
if (System.getenv('CI')) {
println 'Running in CI environment'
}



gradle.properties: Project-level, global (~/.gradle)

Файл gradle.properties используется для определения свойств Gradle, JVM и проекта.

Project-level (projectDir/gradle.properties):
Применяется к конкретному проекту.

Пример:
version=1.0.0
org.gradle.jvmargs=-Xmx2048m
org.gradle.parallel=true


Global (~/.gradle/gradle.properties):
Применяется ко всем проектам на машине.

Пример:
org.gradle.caching=true
org.gradle.jvmargs=-Xmx4096m


Использование:
Свойства доступны через project.property:println project.version
В памяти: Свойства загружаются как часть модели проекта на фазе инициализации, добавляя минимальный overhead (5-10 МБ). Глобальный gradle.properties парсится для всех сборок, увеличивая время инициализации.


Нюансы:
Храните чувствительные данные (например, ключи API) в ~/.gradle/gradle.properties с ограниченными правами (chmod 600).
Используйте для централизованных настроек, таких как JVM-память или включение кэширования.



Использование -P, -D, --info, --debug, --scan

Gradle предоставляет командные параметры для настройки и отладки сборки.

-P:
Задает свойства проекта.

Пример:
./gradlew build -PmyProperty=value


Доступ:
println project.hasProperty('myProperty') ? project.myProperty : 'default'


-D:
Задает системные свойства JVM.

Пример:
./gradlew build -Dorg.gradle.jvmargs=-Xmx2048m


--info:
Выводит информационные логи.

Пример:
./gradlew build --info


--debug:
Выводит подробные логи для отладки.

Пример:
./gradlew build --debug


--scan:
Генерирует Build Scan для анализа сборки.

Пример:
./gradlew build --scan


Требует настройки плагина:
plugins {
id 'com.gradle.build-scan' version '3.17.4'
}
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}


В памяти: Параметры -P и -D добавляют свойства в модель проекта или JVM, минимально влияя на память. Логи --info и --debug увеличивают объем вывода, а --scan загружает метаданные сборки в память (50-100 МБ для крупных проектов).


Нюансы:
Используйте --scan для анализа производительности и выявления узких мест.
Параметры -P и -D имеют приоритет над
gradle.properties.


Lazy vs Eager Configuration

Gradle поддерживает два подхода к конфигурации: eager (немедленная) и lazy (ленивая).

Eager Configuration:
Вычисления выполняются на фазе конфигурации, даже если задача не выполняется.

Пример:
task example {
def value = computeExpensiveValue()
doLast {
println value
}
}


Lazy Configuration:
Вычисления откладываются до фазы выполнения с использованием Provider или Property.

Пример:
task example {
def value = providers.provider { computeExpensiveValue() }
doLast {
println value.get()
}
}


В памяти: Ленивая конфигурация снижает потребление памяти на фазе конфигурации, так как значения вычисляются только при необходимости. Eager-конфигурация загружает все значения сразу, увеличивая overhead (до 100-200 МБ для сложных скриптов).


#Java #middle #Gradle #Task #deploy
👍1
Конфигурационные API: Provider, Property, ListProperty

Gradle предоставляет API для ленивой конфигурации, что улучшает производительность и гибкость.

Provider:
Интерфейс для ленивых значений, вычисляемых при необходимости.

Пример:
def versionProvider = providers.provider { project.version }
task printVersion {
doLast {
println "Version: ${versionProvider.get()}"
}
}


Property:
Для управления одиночными значениями.

Пример:
task example {
def outputFile = objects.property(String)
outputFile.set('build/output.txt')
doLast {
println "Output: ${outputFile.get()}"
}
}


ListProperty:
Для управления списками значений.

Пример:
task example {
def files = objects.listProperty(String)
files.set(['file1.txt', 'file2.txt'])
doLast {
files.get().each { println it }
}
}


Kotlin DSL:
tasks.register("example") {
val outputFile = objects.property<String>()
outputFile.set("build/output.txt")
doLast {
println("Output: ${outputFile.get()}")
}
}


В памяти: Provider, Property и ListProperty хранят ссылки на значения, а не сами значения, минимизируя потребление памяти до фазы выполнения. Это снижает overhead на фазе конфигурации (экономия 10-50 МБ на задачу).


Нюансы:
Используйте Provider для динамических вычислений.
Property и ListProperty обеспечивают строгую типизацию, особенно в Kotlin DSL.



Ext-переменные (ext {})

Блок ext позволяет определять пользовательские свойства для проекта или объектов.

Пример:
ext {
myVersion = '1.0.0'
myProperty = 'value'
}
task printExt {
doLast {
println project.ext.myVersion
}
}


Kotlin DSL:
extra["myVersion"] = "1.0.0"
extra["myProperty"] = "value"
tasks.register("printExt") {
doLast {
println(project.extra["myVersion"])
}
}


Использование:
Для хранения общих констант (например, версий зависимостей).
Для передачи данных между задачами или модулями.


В памяти: ext-переменные хранятся как часть модели проекта, добавляя минимальный overhead (менее 10 МБ). Однако большое количество переменных может усложнить модель.


Нюансы:
Избегайте чрезмерного использования ext в пользу Version Catalog для версий зависимостей.
Используйте для кастомных настроек, не связанных с зависимостями.


buildSrc/ директория

Директория buildSrc позволяет определять кастомную логику (плагины, задачи) в проекте.


Структура:
my-project/
├── buildSrc/
│ ├── src/main/groovy/com/example/MyPlugin.groovy
│ ├── build.gradle
├── build.gradle
├── settings.gradle


Пример плагина (buildSrc/src/main/groovy/com/example/MyPlugin.groovy):
package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project

class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.tasks.register('myTask') {
doLast {
println 'Hello from buildSrc plugin!'
}
}
}
}


Настройка (buildSrc/build.gradle):
plugins {
id 'groovy'
}


Использование:
apply plugin: 'com.example.my-plugin'


Kotlin DSL:
Создайте buildSrc/src/main/kotlin/com/example/MyPlugin.kt:
package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project

class MyPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.register("myTask") {
doLast {
println("Hello from buildSrc plugin!")
}
}
}
}


Настройте buildSrc/build.gradle.kts:
plugins {
`kotlin-dsl`
}


В памяти: buildSrc компилируется как отдельный проект, добавляя собственный classpath и зависимости в JVM. Это увеличивает потребление памяти (100-200 МБ), особенно если buildSrc включает сложные плагины.


Нюансы:
buildSrc автоматически доступен всем модулям проекта.
Используйте для кастомных задач и плагинов, специфичных для проекта.
Для повторно используемых плагинов предпочтительнее создавать отдельный проект и публиковать в репозиторий.



#Java #middle #Gradle #Task #deploy
👍1
Shared Build Logic через init-скрипты

Init-скрипты позволяют задавать глобальную логику, применяемую ко всем Gradle-сборкам.


Настройка:

Создайте файл ~/.gradle/init.d/my-init.gradle:
allprojects {
repositories {
mavenCentral()
}
}
gradle.projectsLoaded {
rootProject.tasks.register('globalTask') {
doLast {
println 'Global task from init script'
}
}
}


Kotlin DSL (~/.gradle/init.d/my-init.gradle.kts):
allprojects {
repositories {
mavenCentral()
}
}
gradle.projectsLoaded {
rootProject.tasks.register("globalTask") {
doLast {
println("Global task from init script")
}
}
}


Использование:
Init-скрипты автоматически применяются ко всем проектам.

Можно указать скрипт явно:
./gradlew build --init-script my-init.gradle


В памяти: Init-скрипты загружаются на фазе инициализации, добавляя задачи и конфигурации в модель проекта. Это увеличивает overhead (10-50 МБ), но распределяется между всеми сборками.


Нюансы:
Используйте для глобальных настроек (например, репозитории, JVM-параметры).
Избегайте сложной логики, чтобы не замедлять инициализацию.



Gradle Wrapper (gradlew): настройка и версионирование

Gradle Wrapper (gradlew) — это скрипт, обеспечивающий воспроизводимость сборки с фиксированной версией Gradle.

Настройка:
Сгенерируйте Wrapper:
gradle wrapper --gradle-version 8.1


Создает файлы:
my-project/
├── gradlew
├── gradlew.bat
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ ├── gradle-wrapper.properties


gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip


Использование:
Запускайте сборку через Wrapper:
./gradlew build


Wrapper загружает указанную версию Gradle, если она отсутствует в ~/.gradle/wrapper.

Версионирование:

Обновите версию:
./gradlew wrapper --gradle-version 8.2


Используйте конкретную версию для согласованности в CI/CD.

В памяти: Wrapper загружает Gradle в отдельный JVM-процесс, добавляя базовый overhead (200-300 МБ). Кэширование дистрибутива в ~/.gradle/wrapper минимизирует сетевые запросы.


Нюансы:
Всегда включайте Wrapper в репозиторий для воспроизводимости.
Проверяйте целостность distributionUrl для безопасности (используйте HTTPS).
Настройте прокси в
gradle-wrapper.properties, если требуется:systemProp.http.proxyHost=proxy.example.com
systemProp.http.proxyPort=8080



#Java #middle #Gradle #Task #deploy
👍1
Тестирование в Spring
1. Простые юнит тесты через TDD в Spring

Серия видео посвященная тестированию всего и вся в Spring.

Что мы рассмотрели:
🔵 Что такое TDD, его принципы и как по нему работать в java
🔵 Рассмотрели простое юнит создание тестов, как с поднятием контекста, так и без.
🔵 Узнали для чего те или иные аннотации без которых не получится написать тесты.
Написали минимальный Spring-сервис через TDD, написав сначала тесты.

Ссылка на Youtube
Ссылка на Рутьюб

Ссылка на GitHub - жду ваших звезд ☺️

Смотрите, ставьте лайки, подписывайтесь на каналы!✌️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Что выведет код?

public class Task060825 {
public static void main(String[] args) {
int x = 1;
int y = 2;

if (++x > y++ ? x++ < --y : y-- > ++x) {
System.out.println("A: x=" + x + " y=" + y);
} else {
System.out.println("B: x=" + x + " y=" + y);
}
}
}


#Tasks
🤯2👍1
Варианты ответа:
Anonymous Quiz
19%
A: x=2 y=2
24%
B: x=2 y=3
5%
A: x=3 y=1
52%
B: x=3 y=2
👍3
Карточка для запоминания double 😎

#memory_card
🔥1
Что такое SoftReference и когда ее использовать? 🤓

Ответ:

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

Пример:
SoftReference<String> softRef = new SoftReference<>(new String("cache"));
System.out.println(softRef.get()); // cache
System.gc(); // Может не удалить, если память не нужна

В отличие от WeakReference, SoftReference живет дольше, что делает ее предпочтительной для кэширования.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
📌 Факт дня:

А вы знали, что первый компьютерный "диспетчер задач" был создан в 1981 году?

Система Xerox Star представила интерфейс для управления запущенными процессами, позволяя переключаться между задачами. Это был прообраз современных диспетчеров задач Windows и macOS.

proof

#facts
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🗓 История IT сегодня — 7 августа


ℹ️ Кто родился в этот день

Джи́мми До́нал Уэ́йлс (англ. Jimmy Donal Wales, также известный под псевдонимом Джи́мбо (англ. Jimbo); род. 7 августа 1966, Хантсвилл, Алабама, США) — американский и британский интернет-предприниматель, один из создателей концепции «вики», основатель онлайн-энциклопедии Википедии.

🌐 Знаковые события

1944 — Презентация IBM Mark I (ASCC)
Первый крупный механический программируемый компьютер, использовался для инженерных расчётов во Второй мировой.

1955 — Первый транзисторный радиоприёмник (Sony TR‑55)
Появление портативной электроники и начало эры миниатюрных устройств.

1959 — Запуск спутника Explorer 6 (США)
Первое в истории изображение Земли, переданное из космоса.

1981 — IBM представила первый ПК (IBM 5150)
Начало массовой компьютеризации, предтеча всех современных персональных компьютеров.

1991 — Публикация World Wide Web
Тим Бернерс‑Ли сделал первую веб‑страницу доступной в сети. Рождение современного Интернета.



#Biography #Birth_Date #Events #7Августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Switch/case в Java

Оператор switch в Java позволяет выбирать, какой код выполнять, в зависимости от значения переменной. Он часто используется вместо множества if-else условий, когда нужно проверить одно значение на совпадение с несколькими вариантами. С Java 14 switch также поддерживает switch expressions (выражения), которые делают код короче и удобнее.

1. Что такое switch в Java?

switch — это условный оператор, который проверяет значение переменной и выполняет соответствующий блок кода в зависимости от совпадения с заданными вариантами (case). Switch expressions — это улучшенная версия switch, которая позволяет возвращать значение и писать более компактный код.

Зачем нужен switch?
Простота выбора: Удобен, когда нужно выбрать действие из нескольких вариантов.
Читаемость: Делает код чище, чем длинная цепочка if-else.
Гибкость: Поддерживает разные типы данных и новые возможности (switch expressions).
Эффективность: В некоторых случаях работает быстрее, чем if-else.



2. Синтаксис switch

2.1. Классический switch (оператор)
Классический switch выполняет блок кода для совпадающего case и использует break, чтобы выйти из конструкции.

Синтаксис:
switch (выражение) {
case значение1:
// Код для значения1
break;
case значение2:
// Код для значения2
break;
default:
// Код, если ни один case не совпал
}


Пример:
int day = 3;
switch (day) {
case 1:
System.out.println("Понедельник");
break;
case 2:
System.out.println("Вторник");
break;
case 3:
System.out.println("Среда");
break;
default:
System.out.println("Другой день");
}

Вывод: Среда


2.2. Switch Expression (с Java 14)
Switch expressions позволяют возвращать значение и использовать стрелочный синтаксис (->) для упрощения кода. Они не требуют break, так как автоматически завершают выполнение.

Синтаксис:
switch (выражение) {
case значение1 -> результат1;
case значение2 -> результат2;
default -> результат_по_умолчанию;
}


Пример:
int day = 3;
String dayName = switch (day) {
case 1 -> "Понедельник";
case 2 -> "Вторник";
case 3 -> "Среда";
default -> "Другой день";
};
System.out.println(dayName);

Вывод: Среда


Примечания к синтаксису:
Поддерживаемые типы:
Классический switch: byte, short, int, char, String, enum.
Switch expression: Те же типы + возможность возвращать значения.
break: В классическом switch нужен, чтобы избежать "проваливания" (fall-through) в следующий case.
default: Выполняется, если ни один case не совпал. Необязателен, но рекомендуется.
Стрелочный синтаксис (->): Используется в switch expressions для компактности.


#Java #для_новичков #beginner #switch_case
👍3