├── roadmap
└── road.png
├── commonmedia
├── defaultFooter.jpg
└── justTheoryFooter.png
├── lessons
├── vcs
│ └── 009
│ │ ├── picture1.png
│ │ ├── picture2.png
│ │ ├── picture3.png
│ │ ├── picture4.png
│ │ ├── picture5.png
│ │ └── picture6.png
├── java-core
│ ├── 007
│ │ ├── exercise4.png
│ │ └── Methods. VarArgs. Overloading method. Recursion.md
│ ├── 012
│ │ ├── accessModifiers.png
│ │ └── Encapsulation. Packages. Access modifiers. Getters and setters.md
│ ├── 018
│ │ └── Check types.md
│ ├── 004
│ │ └── Cycles.md
│ ├── 005
│ │ └── Arrays.md
│ ├── 002
│ │ └── Console input-output. Basic operations. Conditional Expressions.md
│ ├── 017
│ │ └── Enum.md
│ ├── 001
│ │ └── Basic program structure, variables, data types, etc.md
│ ├── 021
│ │ └── Immutable objects.md
│ ├── 014
│ │ └── Polymorphism. Overriding method. Types of polymorphism.md
│ ├── 016
│ │ └── Abstract classes and interfaces.md
│ ├── 003
│ │ └── Type casting. Conditional operators and little bit about Strings.md
│ ├── 019
│ │ └── Object methods.md
│ ├── 013
│ │ └── Inheritance. Keywords extends and super. Access modifier protected.md
│ └── 010
│ │ └── Fields. Keyword static. Constants.md
├── pet-projects
│ ├── petProject.png
│ └── Pet project.md
├── testing
│ ├── 124
│ │ └── testingTypes.png
│ └── 125
│ │ └── projectStructure.png
├── environment
│ └── 0
│ │ ├── jdkStructure.png
│ │ └── Set up environment.md
├── orm-and-jpa
│ ├── 156
│ │ ├── entityLifecycle.png
│ │ └── jpaArchitecture.png
│ ├── 162
│ │ └── criteriaInterfaceHierarchy.png
│ └── 165
│ │ └── secondLevelCacheDiagram.png
├── web-and-java-ee
│ ├── 135
│ │ └── Web. Java EE. Intruduction.md
│ ├── 139
│ │ └── HTTP clients.md
│ ├── 140
│ │ ├── application.png
│ │ └── serverCabinet.png
│ ├── 141
│ │ ├── tomcatHomePage.png
│ │ └── Tomcat. Installation and alternatives.md
│ ├── 143
│ │ ├── servletLifecycle.png
│ │ └── requestProcessingFlow.png
│ ├── 148
│ │ └── requestProcessingFlow.png
│ ├── 151
│ │ ├── jspExample.png
│ │ ├── authFormEmpty.png
│ │ └── authFormFilledIn.png
│ └── 152
│ │ └── tomctDefaultErrorPage.png
├── spring-framework
│ └── 175
│ │ └── beanInitProcess.png
├── out-of-classification
│ └── 160
│ │ └── singletonUml.png
├── libraries-and-build-systems
│ ├── 119
│ │ └── Maven. What's next.md
│ ├── 120
│ │ └── gradleProjectStructure.png
│ ├── 121
│ │ ├── gradleLifecycle.png
│ │ └── gradleTaskGraphes.png
│ ├── 122
│ │ ├── javaDependencyConfigurations.png
│ │ ├── javaTestDependencyConfigurations.png
│ │ └── Gradle. Dependencies.md
│ └── 123
│ │ └── Gradle Wrapper. What's next.md
├── oop
│ └── 011
│ │ └── OOP. Introduction.md
└── jdbc
│ ├── 128
│ └── JDBC introduction. Connection.md
│ └── 132
│ └── JDBC. Tranastions.md
├── .gitignore
├── forcontributors
└── mdCodeStyle.xml
└── README.md
/roadmap/road.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/roadmap/road.png
--------------------------------------------------------------------------------
/commonmedia/defaultFooter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/commonmedia/defaultFooter.jpg
--------------------------------------------------------------------------------
/lessons/vcs/009/picture1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/vcs/009/picture1.png
--------------------------------------------------------------------------------
/lessons/vcs/009/picture2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/vcs/009/picture2.png
--------------------------------------------------------------------------------
/lessons/vcs/009/picture3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/vcs/009/picture3.png
--------------------------------------------------------------------------------
/lessons/vcs/009/picture4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/vcs/009/picture4.png
--------------------------------------------------------------------------------
/lessons/vcs/009/picture5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/vcs/009/picture5.png
--------------------------------------------------------------------------------
/lessons/vcs/009/picture6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/vcs/009/picture6.png
--------------------------------------------------------------------------------
/commonmedia/justTheoryFooter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/commonmedia/justTheoryFooter.png
--------------------------------------------------------------------------------
/lessons/java-core/007/exercise4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/java-core/007/exercise4.png
--------------------------------------------------------------------------------
/lessons/pet-projects/petProject.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/pet-projects/petProject.png
--------------------------------------------------------------------------------
/lessons/testing/124/testingTypes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/testing/124/testingTypes.png
--------------------------------------------------------------------------------
/lessons/environment/0/jdkStructure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/environment/0/jdkStructure.png
--------------------------------------------------------------------------------
/lessons/java-core/012/accessModifiers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/java-core/012/accessModifiers.png
--------------------------------------------------------------------------------
/lessons/testing/125/projectStructure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/testing/125/projectStructure.png
--------------------------------------------------------------------------------
/lessons/orm-and-jpa/156/entityLifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/orm-and-jpa/156/entityLifecycle.png
--------------------------------------------------------------------------------
/lessons/orm-and-jpa/156/jpaArchitecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/orm-and-jpa/156/jpaArchitecture.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/140/application.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/140/application.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/151/jspExample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/151/jspExample.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/140/serverCabinet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/140/serverCabinet.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/141/tomcatHomePage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/141/tomcatHomePage.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/151/authFormEmpty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/151/authFormEmpty.png
--------------------------------------------------------------------------------
/lessons/spring-framework/175/beanInitProcess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/spring-framework/175/beanInitProcess.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/143/servletLifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/143/servletLifecycle.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/151/authFormFilledIn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/151/authFormFilledIn.png
--------------------------------------------------------------------------------
/lessons/orm-and-jpa/165/secondLevelCacheDiagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/orm-and-jpa/165/secondLevelCacheDiagram.png
--------------------------------------------------------------------------------
/lessons/out-of-classification/160/singletonUml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/out-of-classification/160/singletonUml.png
--------------------------------------------------------------------------------
/lessons/orm-and-jpa/162/criteriaInterfaceHierarchy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/orm-and-jpa/162/criteriaInterfaceHierarchy.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/143/requestProcessingFlow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/143/requestProcessingFlow.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/148/requestProcessingFlow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/148/requestProcessingFlow.png
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/152/tomctDefaultErrorPage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/web-and-java-ee/152/tomctDefaultErrorPage.png
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/121/gradleLifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/libraries-and-build-systems/121/gradleLifecycle.png
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/121/gradleTaskGraphes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/libraries-and-build-systems/121/gradleTaskGraphes.png
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/120/gradleProjectStructure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/libraries-and-build-systems/120/gradleProjectStructure.png
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/122/javaDependencyConfigurations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/libraries-and-build-systems/122/javaDependencyConfigurations.png
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/122/javaTestDependencyConfigurations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KFalcon2022/lessons/HEAD/lessons/libraries-and-build-systems/122/javaTestDependencyConfigurations.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### IntelliJ IDEA ###
2 | .idea/
3 | *.iws
4 | *.iml
5 | *.ipr
6 | out/
7 |
8 | ### Eclipse ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### NetBeans ###
21 | /nbproject/private/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
26 |
27 | ### VS Code ###
28 | .vscode/
29 |
30 | ### Mac OS ###
31 | .DS_Store
32 | /.idea/
33 |
34 | ### Obsidian ###
35 | /.obsidian
36 |
--------------------------------------------------------------------------------
/forcontributors/mdCodeStyle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lessons/java-core/018/Check types.md:
--------------------------------------------------------------------------------
1 | # Проверки типов в Java
2 |
3 | При разборе наследования мы сталкивались с даункастингом. И те, кто делал практику, обратили внимание, как неудобно было
4 | реализовывать проверки для него. Java имеет как минимум два механизма, упрощающие подобную логику. О них мы и поговорим
5 | сегодня.
6 |
7 | ## Ключевое слово instanceof
8 |
9 | Первый из способов представлен отдельным оператором. Для первого знакомства с ним предлагаю
10 | изучить [статью](https://metanit.com/java/tutorial/3.10.php).
11 |
12 | Часть информации из нее мы уже знаем, оставшаяся как раз посвящена `instanceof`.
13 |
14 | Отметим несколько важных моментов:
15 |
16 | * По-настоящему удобным синтаксис `instanceof` стал лишь в Java 16, до этого было необходимо реализовывать проверку на
17 | тип и после делать явный каст к типу. Теперь это не обязательно;
18 | * `instanceof` НЕ гарантирует, что проверяемый объект принадлежит к нужному классу. Он проверяет лишь то, что нужный
19 | класс есть в иерархии проверяемого объекта. Т.е. `sthObj instanceof Object` будет `true` для любого объекта, вне
20 | зависимости от его настоящего типа.
21 |
22 | В большинстве случаев, функциональности `instanceof` достаточно. Если же нам нужна большая точность — стоит
23 | использовать способ из следующего подраздела.
24 |
25 | ## Методы Object: getClass()
26 |
27 | Следующий урок будет полностью посвящен классу `Object` и его методам. Однако один из них мы разберем сегодня.
28 |
29 | Метод `getClass()` возвращает объект типа `Class`, соответствующий классу, которому принадлежит изначальный объект.
30 |
31 | **Class** — класс, описывающий класс (тип данных) как сущность. Через него можно получить доступ к информации о
32 | названии, полях, методах и другим данным о классе, которому принадлежит объект.
33 |
34 | Объект класса `Class` можно получить двумя способами: первый — через метод `getClass()` у объекта — мы уже увидели,
35 | второй относится к функциональности класса (как типа данных) - об этом ниже.
36 |
37 | Мы знаем, что у классов могут быть статические поля и методы. Обращение к ним можно описать как
38 |
39 | ```
40 | ./()
41 | ```
42 |
43 | Но кроме этого у каждого класса есть **литерал класса**, который предоставляет объект класса `Class`. Обращение к
44 | этому литералу очень похоже на обращение к статическому полю (хоть им и не является):
45 |
46 | ```
47 | SthClass.class
48 | ```
49 |
50 | На основании этого, мы можем сравнить настоящий тип конкретного объекта с интересующим нас классом следующим образом:
51 |
52 | ```java
53 | SthClass sthClass = new SthClass();
54 | sthClass.getClass().equals(SthClass.class); //true
55 | ```
56 |
57 | С методом `equals()` мы уже неоднократно встречались, используя его можно сравнить любые объекты.
58 | В т.ч. и объекты типа `Class`.
59 |
60 | Несмотря на обилие новой информации, тема достаточно простая, на данном этапе она лишь предлагает два способа получения
61 | информации о принадлежности объекта определенному типу данных (классу). Оба способа можно использовать как обычное
62 | условное выражение, в том числе проверять в `if()` и пр.
63 |
64 | #### С теорией на сегодня все!
65 |
66 | 
67 |
68 | Переходим к практике:
69 |
70 | ## Задача:
71 |
72 | Реализовать
73 | [задачу](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson13_inheritance/task2)
74 | используя изученные способы проверки типа.
75 |
76 | 1. используйте `instanceof`;
77 | 2. используйте `getClass()`.
78 |
79 | Какой из способов больше подходит для данной задачи? Почему?
80 |
81 | **Разбор практики для этого урока**:
82 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson18_instanceof_getClass)
83 |
84 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
85 | >
86 | > Канал: https://t.me/ViamSupervadetVadens
87 | >
88 | > Мой тг: https://t.me/ironicMotherfucker
89 | >
90 | > **Дорогу осилит идущий!**
91 |
--------------------------------------------------------------------------------
/lessons/java-core/004/Cycles.md:
--------------------------------------------------------------------------------
1 | # Циклы
2 |
3 | ## Первое знакомство
4 |
5 | **Цикл** – синтаксическая языковая конструкция, позволяющая выполнять однотипные действия определенное количество раз.
6 | При этом количество повторений (**итераций**) может быть как известно заранее, так и нет.
7 |
8 | Рассмотрим подробнее на основании [статьи](https://metanit.com/java/tutorial/2.6.php). Не забывайте о вопросах для
9 | самопроверки и упражнения!
10 |
11 | Также видео:
12 | [](https://www.youtube.com/watch?v=wlKQBgJqPRs)
13 |
14 | Если вы уже самостоятельно изучили массивы, в качестве закрепляющего материала по циклам могу предложить данные 3
15 | коротких видео:
16 |
17 | 1. [while и do-while](https://www.youtube.com/watch?v=Q2DXFrzYWJs&list=PL786bPIlqEjRDXpAKYbzpdTaOYsWyjtCX&index=41)
18 | 2. [for](https://www.youtube.com/watch?v=6Vnm9T4NC2k&list=PL786bPIlqEjRDXpAKYbzpdTaOYsWyjtCX&index=42)
19 | 3. [for-each](https://www.youtube.com/watch?v=hJtlhIm-BEo&list=PL786bPIlqEjRDXpAKYbzpdTaOYsWyjtCX&index=43)
20 |
21 | Тем, кто с массивами еще не знаком – вероятно, будет рано, можете пересмотреть после следующего урока.
22 |
23 | ### Итак, что же стоит отметить для себя по циклам:
24 |
25 | * Синтаксис цикла `for`;
26 | * Отличие между `for` и `while`;
27 | * Отличие от `while` и `do-while`;
28 | * Способы создания бесконечного цикла;
29 | * Назначение операторов `break` и `continue`.
30 |
31 | Также несколько важных моментов, которые редко пишут в статьях и еще реже в них читают:
32 |
33 | 1. Цикл `for` принято использовать в тех ситуациях, когда количество производимых итераций заранее известно;
34 | 2. Следуя из п.1 – никогда не реализуйте бесконечный цикл через `for`;
35 | 3. Цикл `while` – наоборот, обычно используется для сценариев, когда количество повторений заранее не прогнозируемо;
36 | 4. Цикл `do-while` в целом редкий в реальном использовании инструмент. Но идеологически он ближе к `while`;
37 | 5. Изменение переменной-**итератора** (в примерах – обычно `int i`) в теле (то, что между `{}`) цикла `for` –
38 | недопустимо. Синтаксически это не является ошибкой, но на практике усложняет восприятие кода;
39 | 6. Не рекомендуется использовать в цикле `for` операторы `break` и `continue`. Поскольку это нарушает п.1.
40 |
41 | Эти правила могут быть не усвоены сейчас. Но искренне надеюсь, что они будут восприниматься как данность к моменту,
42 | когда вы напишете свою первую строчку кода на реальном проекте.
43 |
44 | Также следует отметить, что мы можем в любом нужном нам виде совмещать использование различных языковых конструкций:
45 | использовать условные конструкции в циклах, циклы в условных конструкциях, циклы в циклах – главное, чтобы такое
46 | использование было обосновано.
47 |
48 | #### С теорией на сегодня все!
49 |
50 | 
51 |
52 | Переходим к практике. Часть заданий может показаться знакомой:
53 |
54 | ## Задача 1:
55 |
56 | Ввести с клавиатуры целое число. Вывести в консоль его факториал.
57 |
58 | ## Задача 2:
59 |
60 | Ввести с клавиатуры целое число. Вывести в консоль сумму цифр введенного числа.
61 |
62 | ## Задача 3:
63 |
64 | Написать программу, которая принимает длину и ширину прямоугольника (2 целых числа). Нарисовать в консоли заданный
65 | прямоугольник, используя `-` и `|`. Углы прямоугольника обозначить символом ` ` (пробел). Каждая единица длины должна
66 | обозначаться одним символом `-`, каждая единица ширины – символом `|`.
67 |
68 | ## Задача 4:
69 |
70 | Ввести с клавиатуры целое число (Число 2). Для каждого из чисел от 1 до 10 выполнить:
71 |
72 | Если _Число1_ четное, вывести сумму двух чисел (пр.1), если нет - разность (пр.2). Также если числа равны - вывести
73 | надпись `Числа равны!`.
74 |
75 | пр1.: `Число1 + Число2 = Сумма`, где `Число1` - значение 1-го числа (от 1 до 10), `Число2` - значение введенного с
76 | клавиатуры числа, `Сумма` - результат сложения.
77 |
78 | пр2.: `Число1 - Число2 = Разность`, где `Число1` - значение 1-го числа (от 1 до 10), `Число2` - значение введенного с
79 | клавиатуры числа, `Разность` - результат вычитания.
80 |
81 | ## Задача 5:
82 |
83 | Выводить на экран `Не угадал!` до тех пор, пока с клавиатуры не будет введено число `1`. Запрашивать число с клавиатуры:
84 |
85 | Вариант 1: перед выводом на экран `Не угадал!`
86 | Вариант 2: после вывода на экран `Не угадал!`
87 |
88 | Подумать, где стоило бы использовать цикл `do-while`, а где – нет.
89 |
90 | **Разбор практики для этого урока**:
91 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson4_cycles)
92 |
93 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
94 | >
95 | > Канал: https://t.me/ViamSupervadetVadens
96 | >
97 | > Мой тг: https://t.me/ironicMotherfucker
98 | >
99 | > **Дорогу осилит идущий!**
100 |
--------------------------------------------------------------------------------
/lessons/java-core/005/Arrays.md:
--------------------------------------------------------------------------------
1 | # Массивы. И снова циклы
2 |
3 | ## Массивы. Нет, не жилые
4 |
5 | Сегодня мы познакомимся с первой **структурой данных** – массивом.
6 |
7 | Она характеризуется тем, что доступ к ее элементам можно получить по **индексу** – порядковому номеру. Но обо всем по
8 | порядку.
9 |
10 | [Статья](https://metanit.com/java/tutorial/2.4.php)
11 |
12 | Видео 1 (знакомство):
13 | [](https://www.youtube.com/watch?v=v7yZ9okDsS4)
14 |
15 | Видео 2 (некоторые подробности). Осторожно, есть незнакомые элементы:
16 | [](https://www.youtube.com/watch?v=i_IiGj65bJM)
17 |
18 | Итак, на что стоит обратить внимание:
19 |
20 | - Синтаксис массивов. Объявление массива в Java можно написать по-разному. Советую использовать вариант `int[] array`;
21 | - Способы инициализации и заполнения. Они тоже бывают разными. Какой выбрать – зависит от задачи;
22 | - Обращение к элементу массива. Не забывайте, что индексы элементов начинаются с нуля;
23 | - Получение размера массива;
24 | - Все то же самое для многомерных массивов;
25 | - Помните, что многомерные массивы в Java могут быть разной длины. Так называемые «зубчатые» массивы. На практике данная
26 | функциональность мало востребована, поскольку такие ситуации обычно решают, используя иные структуры данных. Но
27 | помнить об этом все равно стоит.
28 |
29 | Также необходимо отметить, что элементы массива, значение которых не задано явно, заполняются значениями по умолчанию:
30 |
31 | - `0` – для целых типов (`byte`, `short`, `int`, `long`);
32 | - `0.0` – для вещественных типов (`float`, `double`);
33 | - `false` – для `boolean`;
34 | - символ с числовым кодом `0` – для `char`;
35 | - `null` – для ссылочных типов, включая `String`.
36 |
37 | ## Цикл foreach. И не только он
38 |
39 | В прошлом уроке мы рассматривали тему циклов. Кстати, пришло время пересмотреть видео, которые в прошлый раз давались
40 | как необязательные:
41 | - [while и do-while](https://www.youtube.com/watch?v=Q2DXFrzYWJs&list=PL786bPIlqEjRDXpAKYbzpdTaOYsWyjtCX&index=41)
42 | - [for](https://www.youtube.com/watch?v=6Vnm9T4NC2k&list=PL786bPIlqEjRDXpAKYbzpdTaOYsWyjtCX&index=42)
43 | - [foreach](https://www.youtube.com/watch?v=hJtlhIm-BEo&list=PL786bPIlqEjRDXpAKYbzpdTaOYsWyjtCX&index=43)
44 |
45 | В большей степени нас интересует последний цикл, поскольку ранее он не разбирался. Однако он упоминался в
46 | [статье metanit](https://metanit.com/java/tutorial/2.4.php) для массивов.
47 |
48 | Кроме синтаксиса, стоит запомнить еще один важный момент: если используя остальные циклы, мы можем изменить значение
49 | элемента массива, доступного по i-му индексу, то цикл `foreach` такой возможности не дает. Но есть нюанс.
50 |
51 | Если мы рассмотрим код:
52 |
53 | ```java
54 | String[] nums = new String[5];
55 | for (String s : nums) {
56 | s = "!";
57 | System.out.println(s);
58 | }
59 |
60 | for (String s : nums) {
61 | System.out.println(s);
62 | }
63 | ```
64 |
65 | То увидим следующее:
66 |
67 | 1. Мы создаем пустой массив строк на 5 элементов;
68 | 2. В первом цикле мы присваиваем текущему элементу массива (`s`) значение `"!"`;
69 | 3. Не выходя из цикла, выводим текущее значение в консоль;
70 | 4. В следующем цикле выводим значение каждого элемента в консоль.
71 |
72 | Если запустить данный код, мы обнаружим в нашей консоли пять восклицательных знаков и пять `null`. Что служит причиной
73 | такого поведения – разберем несколько раз на разных уровнях. Первый раз уже совсем скоро – в теме _«Методы»_.
74 |
75 | #### С теорией на сегодня все!
76 |
77 | 
78 |
79 | Переходим к практике:
80 |
81 | ## Задача 1:
82 |
83 | Создать массив `char`, заполненный буквами своего имени в верном порядке.
84 | Используя этот массив, вывести свое имя в консоль.
85 |
86 | Вариант 1: не используя переменную типа `String`;
87 | Вариант 2: предварительно собрав значения массива в переменную типа `String`.
88 |
89 | Подсказка для варианта 2: создать пустую строку можно так: `String s = "";`
90 |
91 | ## Задача 2:
92 |
93 | Создать массив `int` из 5 элементов. Заполнить его значениями, введенными с клавиатуры. Вывести на экран сумму каждого
94 | значения с предыдущим. Предыдущим значением для 0-го (нулевого) элемента считать последнее значение массива.
95 |
96 | ## Задача 3 (*):
97 |
98 | Вычислить и записать в массив первые 10 простых чисел.
99 |
100 | **Простое число** – положительное целое число, которое делится без остатка лишь на себя и на 1. 1 не является простым
101 | числом.
102 |
103 | Вывести в консоль сумму всех элементов полученного массива.
104 |
105 | **Разбор практики для этого урока**:
106 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson5_arrays)
107 |
108 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
109 | >
110 | > Канал: https://t.me/ViamSupervadetVadens
111 | >
112 | > Мой тг: https://t.me/ironicMotherfucker
113 | >
114 | > **Дорогу осилит идущий!**
115 |
--------------------------------------------------------------------------------
/lessons/environment/0/Set up environment.md:
--------------------------------------------------------------------------------
1 | # Настройка окружения
2 |
3 | Итак, что же это за страшные слова и для чего настраивать окружение?
4 |
5 | Настройки окружения, в узком смысле, подразумевают под собой установку программ, переменных среды и иную конфигурацию
6 | для ПК (в нашем случае), необходимую для работы. Это то, с чем сталкивается каждый, кто начинает свой путь в
7 | программировании и, в целом, каждый разработчик при получении нового ПК.
8 |
9 | На данном этапе, установка окружения для нас сведется к двум пунктам:
10 |
11 | * Установка **JDK**;
12 |
13 | * Установка **IDE**.
14 |
15 | > Примечание: рекомендую обращать внимание на слова/выражения, обозначенные полужирным шрифтом.
16 | > Это та терминология, которой стоит овладеть.
17 |
18 | ## Что такое JDK? Немного ознакомительной информации
19 |
20 | Если в двух словах, то JDK – это то, без чего нельзя выполнить программу, написанную на Java. Данную тему мы будем
21 | разбирать более подробно в дальнейшем, пока буквально несколько строк вводной информации.
22 |
23 | JDK - Java Development Kit – комплект разработчика на Java. Иными словами, это набор инструментов, без которых
24 | разработка невозможна.
25 |
26 | 
27 |
28 | JDK можно разделить на два блока, они выделены оранжевым на картинке выше:
29 |
30 | * Инструменты для разработки. Содержат в себе набор утилит, призванных упрощать разработку на Java. Например, здесь
31 | содержится компилятор (о нем позже) и инструмент для написания документации к программному коду. На данном этапе они
32 | нас интересуют в меньшей степени;
33 |
34 | * **JRE**. Java Runtime Environment. Это инструментарий, который необходим для запуска программ, написанных на Java.
35 | Он в свою очередь состоит из **JVM** – виртуальной машины Java – и библиотеки Java-классов.
36 |
37 | ## Установка JDK
38 |
39 | В зависимости от предпочтительного формата я предлагаю либо ознакомиться с видео:
40 |
41 | [](http://www.youtube.com/watch?v=uXMTq81jG7Y)
42 |
43 | Либо посмотреть инструкции в формате статьи: [ссылка](https://metanit.com/java/tutorial/1.1.php).
44 |
45 | Впрочем, статью рекомендую прочесть в любом случае, она призвана дать первую информацию о новом для вас языке.
46 |
47 | ## IDE. Что это и с чем это едят
48 |
49 | IDE - Integrated development environment, говоря по-русски – интегрированная среда разработки. Инструмент, облегчающий
50 | разработку программ и проектов в комплексе.
51 |
52 | Непосредственно программный код можно писать даже в блокноте. Однако IDE дают возможность гибкой работы со структурой
53 | проекта, его **компиляцией**, отладкой и выполнением, позволяют ускорить написание кода посредством функционала
54 | автодополнения и множества шорт-катов (комбинаций клавиш). Также в современные IDE интегрированы смежные технологии,
55 | которые нужны на разных этапах разработки ПО. Но об этом позже.
56 |
57 | Итак, какие IDE бывают для Java. Вариантов, на самом деле, немного:
58 |
59 | 1. Intellij IDEA;
60 | 2. Eclipse;
61 | 3. NetBeans.
62 |
63 | Последний рекомендую сразу забыть, он не используем на данный момент и его наличие в этом списке – лишь дань уважения.
64 |
65 | Eclipse – популярная бесплатная IDE, которая планомерно уступает свои позиции Intellij IDEA,
66 | за исключением ряда узких направлений. Использовать можно, но не рекомендую. Eclipse дает большую
67 | гибкость настройки, нежели IDEA, однако на начальном этапе это скорее навредит, чем поможет. Впрочем, не на начальном
68 | – зачастую, тоже. Если мои предостережения не остановили, можете поработать с ней.
69 |
70 | Видео по установке:
71 |
72 | [](http://www.youtube.com/watch?v=JuHACj_a0Rw)
73 |
74 | В формате статьи: [ссылка](https://metanit.com/java/tutorial/1.4.php).
75 |
76 | Третий и наиболее предпочтительный вариант – Intellij IDEA. На данный момент наиболее популярная IDE в Java-мире.
77 | Существует в двух версиях: бесплатная – Community edition и за деньги – Enterprise edition. На первых порах нам вполне
78 | хватит бесплатной сборки. Тем более, из РФ и РБ купить платную версию сейчас не очень легко.
79 |
80 | Видео по установке:
81 |
82 | [](http://www.youtube.com/watch?v=tSTvCyqeeYY)
83 |
84 | В формате статьи: [ссылка](https://metanit.com/java/tutorial/1.5.php).
85 |
86 | Немного рекомендаций: IDE, вне зависимости от вашего выбора, является достаточно сложным и комплексным инструментом.
87 | На то, чтобы его полноценно освоить – уходят годы. Хорошая новость в том, что если вы не умеете пользоваться каким-то
88 | функционалом IDE – он, скорее всего, вам пока и не нужен. Однако я рекомендую обращать внимание на подсказки, которые
89 | IDE дает при запуске, постепенно изучать комбинации клавиш – шорткаты – со временем они могут сильно облегчить вашу
90 | жизнь.
91 |
92 | Удачи в установке, если что-то не получается – welcome в комменты к посту или в лс:)
93 |
94 | #### На сегодня все!
95 |
96 | 
97 |
98 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
99 | >
100 | > Канал: https://t.me/ViamSupervadetVadens
101 | >
102 | > Мой тг: https://t.me/ironicMotherfucker
103 | >
104 | > **Дорогу осилит идущий!**
105 |
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/119/Maven. What's next.md:
--------------------------------------------------------------------------------
1 | # Maven. Что дальше?
2 |
3 | Это статья - последняя, посвященная системе сборки Maven. Возможно, в дальнейшем этот подраздел будет расширен, но
4 | на данном этапе кажется достаточным тот материал, который уже опубликован.
5 |
6 | Конечно, остались темы, не затронутые в курсе. Некоторые из них - по важным на практике разделам, вроде
7 | модулей в Maven.
8 |
9 | Ниже будет тезисный набор направлений, по которым имеет смысл углубиться в обучение в дальнейшем. Конечно, в идеале
10 | эти темы нужно постигать на боевом, или приближенным к боевому, проекте. Но при желании они могут быть освоены и
11 | самостоятельно.
12 |
13 | Почему какие-то разделы были опущены? Основных причин две:
14 |
15 | 1. Не слишком популярная функциональность. Как,
16 | например, [профили](https://maven.apache.org/guides/introduction/introduction-to-profiles.html). Они имеют право на
17 | жизнь и могут применяться, в том числе, в реальных проектах. Но далеко не каждый Maven-проект их содержит и
18 | знакомиться с ними сейчас мне кажется избыточным. Тезисно о них рассказали
19 | в [стриме](https://t.me/ViamSupervadetVadens/174), посвященном системам сборки. И выглядит, будто самого факта
20 | информации, что они существуют, будет достаточно на данном этапе;
21 | 2. Тема слишком простая на базовом уровне и/или чаще всего используется в ручном режиме. Яркий пример этого
22 | - [модули](https://maven.apache.org/guides/mini/guide-multiple-modules.html). В них можно нырять глубоко,
23 | рассказывая о различных конфигурациях, настройках связей между различными модулями и прочим. Но на базовом
24 | уровне тема модулей не сильно сложнее пакетов в Java, а IDEA автоматизирует добавление нового модуля, в т.ч.
25 | генерируя pom.xml с поправкой на иерархию модулей. Таким образом, на практике добавление модуля окончательно
26 | сравнивается по сложности с добавлением пакета в Java.
27 |
28 | Гораздо важнее углубляться в те темы и разделы, которые уже были освещены в курсе. Я бы рекомендовал смотреть в
29 | следующих направлениях:
30 |
31 | 1. Более глубокое знакомство со стандартными maven-плагинами. Они имеют различные цели, которые заточены под
32 | специфические задачи. Более подробный разбор поможет лучше понять жизненный цикл приложения и возможности системы
33 | сборки даже "из коробки";
34 | 2. Знакомство с Nexus Repository Manager. Желательно знакомиться с ним по мере необходимости в боевом проекте, но
35 | базово - можно и сейчас;
36 | 3. Maven Wrapper. В разделе с Gradle мы познакомимся с Gradle Wrapper, который, в свою очередь, и стал вдохновителем
37 | аналогичного инструмента в Maven;
38 | 4. Продвинутая конфигурация плагинов. В первую очередь - знакомство (углубление знакомства) с `executions`,
39 | `dependencies` и их актуальностью. Особенно `executions`, возможности этой конфигурации весьма масштабны. Также
40 | сюда стоит отнести конфигурацию плагинов с использованием составных типов данных и коллекций. Эта тема не такая
41 | сложная, с ней просто нужно познакомиться:) Конечно, конфигурация каждого плагина или даже цели - уникальна. Но
42 | общие механизмы и знание стандартных параметров базовых плагинов упрощают конфигурацию Maven, особенно при
43 | создании новых проектов;
44 | 5. Конфигурация плагинов для многомодульных систем. Наследование конфигураций, `pluginManagement`;
45 | 6. Конфигурация зависимостей с использованием наследования и скоуп `import`. Это то, что позволит сэкономить десятки,
46 | если не сотни человеко-часов и километры нервов в больших проектах;
47 | 7. **[BOM](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms)**.
48 | То, что позволит лучше понять, как работает подключение крупных библиотек и фреймворков, которые могут иметь
49 | большое число транзитивных, используемых разными артефактами зависимостей и требуют согласованности версий. Мы еще
50 | затронем эту тему вскользь, изучая Spring Framework;
51 | 8. Написание собственного плагина, даже простого. Кроме того, что иногда такое требуется для решения прикладных задач,
52 | это еще и
53 | позволит избавиться от ощущения "магии из коробки" при использовании существующих плагинов. Понимание того, что
54 | это просто Java-проект (или не Java), написанный по определенным правилам, делает жизнь проще.
55 |
56 | Как и всегда, этот список можно расширять. И у каждого, в конечном итоге, получается свой набор знаний о Maven,
57 | исходя из конкретных задач и проблем, с которыми довелось столкнуться на практике. Возможно, что-то в этом списке
58 | стоило бы заменить иными, более приоритетными пунктами. Как бы там ни было, большую часть из них лучше постигать в
59 | команде, имея под рукой реальный проект, где что-то из описанного уже используется, а главное - имея более опытных
60 | товарищей, которые смогу ответить на вопросы и направить.
61 |
62 | Впрочем, наличие проекта и команды помогает в профессиональном развитии безотносительно изучаемого раздела.
63 |
64 | Впереди нас ждет альтернативная система сборки - Gradle. Во многом похожая на Maven, в чем-то - отличающаяся
65 | (например, отсутствием километровых `pom.xml`). Возможно, знакомство с Gradle позволит и лучше понять отдельные
66 | аспекты, касающиеся Maven.
67 |
68 | Но самое интересное будет после завершения раздела "Системы сборки". Ведь там будет изучение фреймворков и библиотек,
69 | а значит - более естественная практика для применения Maven и Gradle.
70 |
71 | #### На сегодня все!
72 |
73 | 
74 |
75 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
76 | >
77 | > Канал: https://t.me/ViamSupervadetVadens
78 | >
79 | > Мой тг: https://t.me/ironicMotherfucker
80 | >
81 | > **Дорогу осилит идущий!**
82 |
--------------------------------------------------------------------------------
/lessons/java-core/002/Console input-output. Basic operations. Conditional Expressions.md:
--------------------------------------------------------------------------------
1 | # Консольный ввод/вывод. Арифметические операции, операции присвоения. Условные выражения
2 |
3 | ## Консольный ввод/вывод
4 |
5 | Сначала несколько слов об актуальности. Мы уже познакомились с консольным выводом через `System.out.println()`. Данная
6 | статья покажет функции-побратимы, дающие разные фишки, упрощающие вывод на консоль.
7 |
8 | Также впервые встретимся с консольным вводом. Значения, записанные с клавиатуры будут использоваться в качестве значений
9 | переменных.
10 |
11 | Статья для ознакомления: [ссылка](https://metanit.com/java/tutorial/2.9.php)
12 |
13 | На данном этапе мы не будем разбирать, как работает механизм ввода внутри, лишь начнем его использовать для большей
14 | динамичности наших программ. Все же, практика становится интереснее, когда результат зависит не только от кода:)
15 |
16 | На что стоит обратить внимание:
17 |
18 | 1. В чем отличие между `System.out.print()`, `System.out.println()`, `System.out.printf()`;
19 | 2. Какие спецификаторы использует `System.out.printf()`. К слову, в дальнейшем они будут нужны не только для него, так
20 | что советую выучить;
21 | 3. Как ввести данные различных типов через `Scanner`.
22 |
23 | ## Арифметические операции
24 |
25 | Тема арифметических операций достаточно простая, потому что сами операции вполне привычны нам и используются
26 | повседневно. Единственными новыми операциями могут стать **деление по модулю** — операция, позволяющая вычислить остаток
27 | от деления целых чисел, и операции **инкремента**/**декремента**. Чтобы не пугать непонятными словами, предлагаю перейти
28 | к статье: [ссылка](https://metanit.com/java/tutorial/2.3.php).
29 |
30 | На что стоит обратить внимание:
31 |
32 | 1. Результат деления двух целых чисел — всегда целое число. Стоит помнить как этого избежать;
33 | 2. Деление по модулю. Операция простая, однако ее почему-то все стараются забыть;
34 | 3. В чем отличие префиксного и постфиксного инкрементов;
35 | 4. Роль скобок в арифметике.
36 |
37 | Также обратите внимание: в статье на метаните есть вопросы для самопроверки под статьей. Не игнорируйте их.
38 |
39 | ## Условные выражения
40 |
41 | В данном пункте мы разбираем операции сравнения и логические операции. Первое знакомо со школы, второе будет знакомо
42 | всем, кто сталкивался с формальной логикой или, в крайнем случае, изучал электронные приборы:) Даже если ранее вы ничего
43 | не слышали о логических операциях — ничего страшного в них нет, все разберем.
44 |
45 | > Перед прочтением статьи по ссылке, обратите внимание: среди логических операций есть `^`. **Исключающее или**, оно
46 | > же **XOR**. Очень круто, если вы сможете с ним разобраться. Но не дай бог в отсутствие крайней необходимости его
47 | > использовать. Опыт разработки показывает, что логические операции обычно ограничиваются **И**, **ИЛИ**. Иногда из них
48 | > формируются очень длинные цепочки, но о них и о том, почему это нехорошо, мы поговорим позже.
49 |
50 | А теперь — статья: [https://metanit.com/java/tutorial/2.14.php](https://metanit.com/java/tutorial/2.14.php)
51 |
52 | На что стоит обратить внимание:
53 |
54 | 1. Оператор тождественности(равенства) - `==`. Единичное `=` оператор присваивания. Но НЕ равно обозначается как `!=`;
55 | 2. Порядок символов в `>=`,`<=`;
56 | 3. Разница между операторами `&`, `|` и `&&`, `||`.
57 |
58 | ## Операции присваивания для самых ленивых и приоритет операций
59 |
60 | Программисты — люди очень ленивые, поэтому форма записи `i = i + 1` - это не наш метод. И мы используем `i++` Но и
61 | `i = i + 10` - все еще не наш метод, но об это в статье по ссылке ниже.
62 |
63 | > **!NB**: Мы пропустили тему поразрядных операций как бесполезную в Java-разработке. Поэтому в этой статье рекомендую
64 | > проигнорировать то, что связано со следующими операторами:
65 | > * `!=`
66 | > * `&=`
67 | > * `^=`
68 | > * `<<=`
69 | > * `>>=`
70 | > * `>>>=`
71 |
72 | Если вам любопытно, что это и с чем едят — в качестве факультатива можете обратиться к
73 | статье: [ссылка](https://metanit.com/java/tutorial/2.13.php).
74 |
75 | Тем временем, статья по основной теме: [еще одна ссылка](https://metanit.com/java/tutorial/2.15.php).
76 |
77 | Там присутствуют незнакомые нам пока **тернарный оператор** и **ключевое слово** `instanceof` — с ними мы познакомимся
78 | позже.
79 |
80 | #### С теорией на сегодня все!
81 |
82 | 
83 |
84 | Переходим к практике:
85 |
86 | ## Задача 1:
87 |
88 | Введите с клавиатуры вещественные числа `a` и `b`. Выведите на экран результат выражения
89 |
90 | _c = ba(a + b)/(a2)_
91 |
92 | Совпадает ли результат выражения, если `a` и `b` — переменные типа `int` (для проверки не забудьте также использовать
93 | подходящий метод `Scanner`)?
94 |
95 | ## Задача 2:
96 |
97 | Введите с клавиатуры целые числа `a` и `b`. Выведите на экран результат сравнения:
98 |
99 | _a3 > b2_
100 |
101 | ## Задача 3:
102 |
103 | ```java
104 | public class Main {
105 | public static void main(String[] args) {
106 | int a = 1;
107 | int b = a++;
108 | b += a++;
109 | System.out.println(b);
110 | }
111 | }
112 | ```
113 |
114 | Значение b, выведенное на экран совпадает с тем, что вы ожидали увидеть? Если нет, снова идем
115 | читать по [ссылке 1](https://metanit.com/java/tutorial/2.3.php)
116 | и [ссылке 2](https://metanit.com/java/tutorial/2.15.php):)
117 |
118 | **Разбор практики для этого урока**:
119 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson2_operators_console_io)
120 |
121 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
122 | >
123 | > Канал: https://t.me/ViamSupervadetVadens
124 | >
125 | > Мой тг: https://t.me/ironicMotherfucker
126 | >
127 | > **Дорогу осилит идущий!**
128 |
--------------------------------------------------------------------------------
/lessons/java-core/017/Enum.md:
--------------------------------------------------------------------------------
1 | # Enum'ы
2 |
3 | В этом уроке мы немного отвлечемся от ООП и познакомимся с функционалом, который предоставляет Java для **перечисляемых
4 | типов** — **enum'ов**.
5 |
6 | Предлагаю ознакомиться со [статьей](https://metanit.com/java/tutorial/3.8.php).
7 |
8 | И видео:
9 |
10 | [](http://www.youtube.com/watch?v=ll14SKsQScE)
11 |
12 | Также рекомендую для лучшего понимания, как реализован enum в Java, посмотреть еще одно:
13 |
14 | [](http://www.youtube.com/watch?v=aMiemoKyiqU)
15 |
16 | Enum, проводя аналогии, может показаться гибридом констант и реализации наследования, где каждая константа — отдельный
17 | класс наследник. О том, так ли это на самом деле, рассказывает видео выше.
18 |
19 | Обычно enum'ы используются для хранения информации, которая неизменна, но имеет большее влияние на систему, нежели
20 | константы. Например, часто через enum'ы реализуют различные статусы или состояния. Это удобно по двум причинам:
21 |
22 | 1. Нет необходимости **валидировать** значение. В отличие от числовой или строковой константы, переменная/поле enum-типа
23 | примет только значение, указанное как один из элементов enum'а;
24 | 2. Enum'ы могут содержать поля, что позволяет хранить для каждого значения его реальное название/описание или другую
25 | полезную информацию.
26 |
27 | Как можно было заметить из статьи или видео, любой enum имеет набор характерных методов. Отметим те, которые
28 | действительно могут быть полезны. И еще один, о котором просто принято рассказывать новичкам:
29 |
30 | * `valueOf()` — позволяет получить значение (элемент) enum'а по его строковому эквиваленту. Недоступен при обращении к
31 | элементу enum'а;
32 | * `values()` — возвращает массив со всеми значениями enum'а, для которого был вызван. Недоступен при обращении к
33 | элементу enum'а;
34 | * `name()` — метод, противоположный `valueOf()`. Возвращает название элемента в виде строкового значения. Доступен
35 | только при обращении к элементу enum'а;
36 | * `ordinal()` — возвращает порядковый номер элемента enum'а. Практически не используется. Не рекомендую завязывать на
37 | нем какую-то логику. При добавлении нового элемента в начало или середину enum'а, порядковый номер элементов
38 | сдвинется и зависимая логика может сломаться. Доступен только при обращении к элементу enum'а.
39 |
40 | Еще несколько методов мы рассматривать не будем, поскольку они не популярны на практике, а у нас, в любом случае, не
41 | хватает знаний для работы с ними.
42 |
43 | Также для элементов enum'а, как и любого другого объекта, доступны методы `Object`. Мы пока знакомы только с `equals()`.
44 | Но enum'ы также допустимо сравнивать через оператор `==`.
45 |
46 | Стоит обратить внимание на несколько нюансов при использовании enum'ов:
47 |
48 | * В enum'е допустимо хранить поля. Каждое поле стоит помечать как `final`. Изменять значения полей enum'а — плохая
49 | практика;
50 | * Мы можем описать методы для enum'а. Как общие для всего enum'а, так и с отдельной реализацией для каждого элемента.
51 | Первое допустимо и часто используется, второе — плохая практика, поскольку дает enum'у слишком большую зону
52 | ответственности, а код делает трудночитаемым;
53 | * На начальном этапе может казаться, что enum'ы — хорошая альтернатива наследованию. Это не так. Enum'ы в Java имеют
54 | широкую функциональность, но и большие ограничения. На простых примерах использование enum'ов будет проще, чем
55 | полноценная реализация наследования с использованием полиморфизма (мы сравним в практической части), при реализации
56 | сложной логики — скорее всего, enum'ы создадут больше проблем;
57 | * Enum'ы, как и другие классы, должны иметь четко очерченную зону ответственности. Не делайте их слишком тяжелыми;
58 | * Каждый enum необходимо создавать в своем файле. Как классы и интерфейсы;
59 | * Стиль именования для элементов enum'ов может зависеть от проекта. Я рекомендую использовать тот же подход, что и для
60 | констант уровня класса.
61 |
62 | #### С теорией на сегодня все!
63 |
64 | 
65 |
66 | Переходим к практике:
67 |
68 | ## Задача 1:
69 |
70 | Реализуйте
71 | [задачу](https://github.com/KFalcon2022/practical-tasks/blob/master/src/com/walking/lesson3_casts_conditional_constructions/Task2SwitchCase.java)
72 | через enum. В т.ч. реализуйте в enum'е поиск значения по фразе, введенной пользователем. Напоминаю, что enum'ы могут
73 | содержать поля.
74 |
75 | ## Задача 2:
76 |
77 | Реализуйте
78 | [задачу](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson14_polymorphism/task2)
79 | через enum. Пусть `Cow`, `Dog` и `Cat` будут значениями enum'а `Animal`.
80 |
81 | ## Задача 3:
82 |
83 | Реализуйте
84 | [задачу](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson14_polymorphism/task1)
85 | через enum. Пусть `EquilateralTriangle` и `Square` будут значениями enum'а `EquilateralShape`.
86 |
87 | > _Примечание_: практика направлена на то, чтобы познакомиться с функционалом enum'ов в живую. Не все из этого стоит
88 | > повторять на реальных проектах. Если реализации первой и второй задачи (по крайней мере, предполагаемые автором)
89 | > допустимы в ряде случаев, то третья явно не должна реализовываться с помощью enum и ее решение через наследование и
90 | > полиморфизм — наиболее канонично.
91 | >
92 | > Подводя итог, основное назначение enum'ов — константы на максималках. Типы (чего угодно), статусы, состояния. Все то,
93 | > что должно иметь конечное количество неизменяемых значений.
94 |
95 | **Разбор практики для этого урока**:
96 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson17_enum)
97 |
98 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
99 | >
100 | > Канал: https://t.me/ViamSupervadetVadens
101 | >
102 | > Мой тг: https://t.me/ironicMotherfucker
103 | >
104 | > **Дорогу осилит идущий!**
105 |
--------------------------------------------------------------------------------
/lessons/java-core/001/Basic program structure, variables, data types, etc.md:
--------------------------------------------------------------------------------
1 | # Базовая структура программы, переменные, типы данных и все-все-все
2 |
3 | Итак, я надеюсь, что JDK установлены, IDE готовы и мы можем приступать именно к кодингу!
4 |
5 | Те, кто разбирал материалы
6 | [предыдущего поста](https://github.com/KFalcon2022/lessons/blob/master/lessons/environment/0/Set%20up%20environment.md),
7 | мог заметить, что и видео, и в статьях демонстрируется несложная программа, которая выводит в консоль «Hello world!».
8 |
9 | Сегодня мы силами метанита узнаем, что есть что в этой программе, хотя бы в общих чертах. К сожалению,
10 | видео-альтернативы этому не будет: [ссылка](https://metanit.com/java/tutorial/2.11.php).
11 |
12 | Основное, что надо для себя вынести по итогам статьи выше:
13 |
14 | * Каков смысл `;` в Java;
15 | * Для чего нужен `System.out.println()`;
16 | * Как правильно объявить метод `main()` и для чего он нужен;
17 | * Разобраться, влияют ли комментарии на поведение кода.
18 |
19 | На данном этапе многие вещи подаются утрированно. Этого не стоит пугаться, все, до последней буквы, разберем подробно,
20 | но в свое время. Пока примем текущее описание за данность.
21 |
22 | #### Переменные и когда они переменяются
23 |
24 | Те, кто еще помнят хоть что-то из математики, возможно, помнят и о переменных в выражениях. Смысл переменных в
25 | программировании очень похож. Это средство языка, позволяющее хранить и обрабатывать значения в оперативной памяти.
26 |
27 | Для более подробных объяснений также взглянем на [статью](https://metanit.com/java/tutorial/2.1.php).
28 |
29 | Что стоит почерпнуть:
30 |
31 | * Что такое **объявление(декларация) переменной**;
32 | * Что такое **инициализация переменной**;
33 | * Общий **синтаксис** объявления и инициализации переменных;
34 | * В чем отличительная особенность **констант** и как их объявлять.
35 |
36 | Единственное, на чем прошу пока не акцентировать внимание — ключевое слово `var`. Это очень удобный механизм, но на
37 | ранних этапах он многих путает. В дальнейшем, при разборе приведения ссылочных типов, мы затронем то, как работает `var`
38 | и углубимся в некоторые другие особенности его использования.
39 |
40 | Крайне важно по итогам этой статьи отложить себе, что можно и, зачастую, нужно менять значение переменной в рамках
41 | программы. Это позволяет строить нам гибкую логику и часто используется в других механизмах. Но об этом позже.
42 |
43 | > **!NB**: Синтаксисом языка называется набор правил, который описывает порядок использования различных операторов и
44 | конструкций языка. В общем смысле, то же, что и грамматика в живом языке. Подробнее:
45 | > [ссылка на Вики](https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%81_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)).
46 |
47 | #### Типы данных
48 |
49 | Тип данных отвечает за то, какие значения мы можем хранить в переменной и сколько места в памяти будет занимать такая
50 | переменная. Более подробный разбор есть в статье: [ссылка](https://metanit.com/java/tutorial/2.12.php).
51 |
52 | И в видео:
53 |
54 | [](https://www.youtube.com/embed/S1GVLezqYoE)
55 |
56 | Рекомендую изучить оба источника, потому что набор предоставляемой информации отличается в нескольких важных деталях.
57 |
58 | Из того, что точно стоит усвоить:
59 |
60 | * Типы данных бывают **примитивные** и **ссылочные**;
61 | * Примитивных типов в Java ровно 8. Свои примитивные типы мы создавать не можем;
62 | * Ссылочных типов потенциально бесконечное количество. Множество из них предоставляются JDK и сторонними библиотеками.
63 | И, конечно, мы можем создавать свои ссылочные типы для своих задач;
64 | * Немного утрируя, мы можем сказать, что любой ссылочный тип состоит из композиции примитивов и/или других ссылочных
65 | типов;
66 | * Все еще утрируя. Практически любой ссылочный тип мы можем представить как набор примитивов. К этому моменту мы будем
67 | возвращаться время от времени.
68 |
69 | Из ссылочных типов нам пока хватит `String`, для остального еще придет время. На данном этапе искренне советую запомнить,
70 | какие особенности инициализации существуют для различных типов. В каких случаях использовать `""`, а когда - `''`. Для
71 | каких типов мы после числового **литерала** пишем буквы `l`/`d`/`f`.
72 |
73 | #### С теорией на сегодня все!
74 |
75 | 
76 |
77 | Переходим к практике:
78 |
79 | ## Задача 1
80 |
81 | ```java
82 | public class Main {
83 | public static void main(String[] args) {
84 | int a = 5;
85 | int b = 10;
86 |
87 | // место для вашего кода
88 |
89 | System.out.println("Значение а: " + a + ". Значение b: " + b);
90 | }
91 | }
92 | ```
93 |
94 | На месте комментария написать код, который присвоит переменной `a` значение переменной `b` и наоборот.
95 |
96 | _Подсказка: можно использовать третью переменную._
97 |
98 | _Вариант на подумать: реализовать задачу, НЕ используя третью переменную._
99 |
100 | ## Задача 2
101 |
102 | Используя
103 |
104 | 1. Переменную типа `String`;
105 | 2. Несколько переменных типа `char`;
106 | 3. Одну переменную типа `char`.
107 |
108 | вывести свое имя в консоль.
109 |
110 | Вывод в консоль с переходом на новую строку:
111 |
112 | ```java
113 | System.out.println(/*ваша переменная*/);
114 | ```
115 |
116 | Вывод в консоль без перехода на новую строку:
117 | ```java
118 | System.out.print(/*ваша переменная*/);
119 | ```
120 |
121 | Усложнение для внимательных: вывести ваше имя посимвольно, где каждая буква — на новой строке, не используя
122 | `System.out.println()`. Реализуется как с использованием `String`, так и используя `char`.
123 |
124 | **Разбор практики для этого урока**:
125 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson1_varaibles)
126 |
127 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
128 | >
129 | > Канал: https://t.me/ViamSupervadetVadens
130 | >
131 | > Мой тг: https://t.me/ironicMotherfucker
132 | >
133 | > **Дорогу осилит идущий!**
134 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Контакт для связи: [Telegram](https://t.me/ironicMotherfucker)
2 |
3 | Ссылка на канал: [Дорогу осилит идущий](https://t.me/ViamSupervadetVadens)
4 |
5 | # Заметка для контрибьюторов
6 |
7 | Если вы хотите помочь в переносе статей из [telegra.ph](https://telegra.ph) в репозиторий, эта памятка для вас:
8 |
9 | 1. Сделайте fork репозитория;
10 | 2. Подготовьте переносимый урок в формате md-файла. Требования к оформлению можно найти ниже;
11 | 3. Сделайте PR на `master` основного репозитория;
12 | 4. В сообщении к PR укажите Номер урока в [Road Map](https://telegra.ph/Java-Road-Map-04-30) и, опционально его тему;
13 | 5. Напишите мне в [ЛС](https://t.me/ironicMotherfucker) со ссылкой на PR или укажите контакт для связи в описании к PR;
14 | 6. Дальнейшая коммуникация и правки по замечаниям в личном порядке.
15 |
16 | Повторяйте пункты 2-6 для каждого PR.
17 |
18 | Важно: не добавляйте в один PR несколько уроков. Это как затруднит, так и затянет процесс обработки PR.
19 |
20 | Искренняя благодарность каждому, кто поможет в этом муторном процессе❤️
21 |
22 | ## Требования к оформлению статьи
23 |
24 | ### Расположение урока и именование
25 |
26 | * Каждый урок должен располагаться в своем разделе в соответствии с
27 | [Road Map](https://telegra.ph/Java-Road-Map-04-30). Если раздел не существует - вы можете его создать самостоятельно;
28 | * При добавлении раздела его имя указывается на английском, слова разделяются дефисами: `chapter-name`
29 | * Для каждого урока внутри раздела создается директория с номером урока в Road Map. Нумерация сквозная;
30 | * Название md-файла должно содержать название урока на английском. Допустимо использовать пробелы и знаки
31 | препинания. Допустимо упрощение названия от оригинального для большей лаконичности. Пример: `How to name lesson.md`;
32 | * md-файл урока помещается в директорию урока. В итоге путь к нему должен выглядеть примерно так:
33 | `${projectHome}/lessons/chapter-name/666/your-file.md`.
34 |
35 | ### Исходный md-файл
36 |
37 | * Длина строки не должна превышать 120 символов;
38 | * Заголовки и другие элементы, отличные по оформлению от обычного текста должны быть отделены пустой строкой.
39 | Рекомендую настроить форматирование по приложенной схеме (можно применить к IDEA и другим продуктам JetBrains):
40 | [ссылка](./forcontributors/mdCodeStyle.xml)
41 |
42 | ### Изображения и медиа
43 |
44 | * Изображения, используемые сугубо в рамках урока (схемы и другие иллюстрации) должны лежать в директории урока;
45 | * Если изображение используется многократно (футеры "На сегодня все"), оно должно лежать в директории
46 | `${projectHome}/commonmedia`;
47 | * В md-файле используются только относительные ссылки на изображение;
48 | * Название изображения должно быть на английском. Должно быть осмысленным и указано в camelCase:
49 | `collectionHierarchy.png`;
50 | * Ссылки на видео-материалы оформляются через URL на внешний ресурс с превью в виде изображения (через внешний URL),
51 | если это возможно, и альтернативным текстом. Пример (при использовании убрать '\\'):
52 | \[\![JDK SETUP]\(http:\//img.youtube.com/vi/uXMTq81jG7Y/0.jpg)]\(http:\//www\.youtube.com/watch?v=uXMTq81jG7Y)
53 |
54 | ### Заголовки
55 |
56 | * Тема урока обозначается как заголовок уровня H1:
57 |
58 | > '# Тема'
59 |
60 | * Дальнейшие подпункты, в зависимости от уровня, обозначаются заголовками уровня H2-H4, в соответствии с
61 | оригинальной структурой. Заголовок H3 может идти исключительно как подпункт заголовка H2. H4 - только как подпункт
62 | H3. При сомнениях - помечайте подобные места собственными замечаниями к PR.
63 |
64 | > '## Пункт урока'
65 | >
66 | >'### Подпункт урока'
67 | >
68 | >'#### Наименьший из возможных подпунктов. Вроде бы не использовался в переносимых статьях.'
69 |
70 | ### Оформление кода
71 |
72 | * Вставки названий переменных, классов, методов и других элементов кода в обычном тексте должны быть оформлены как
73 | код: `someVarName`, `someMethodName()`;
74 | * При указании методов в тексте, они всегда должны содержать скобки. Параметры можно опустить или записать в
75 | упрощенном виде зависимости от контекста: `equals()`, `equals(Object)`;
76 | * При указании отношения конкретного метода к конкретному классу в обычном тексте должны использоваться следующие
77 | обозначения:
78 | * `ClassName.methodName()` - для статических методов. Параметры могут быть опущены или описаны в упрощенной форме,
79 | если контекст это позволяет;
80 | * `ClassName#methodName()` - для не статических методов. В старых статьях обычно использовался символ ':' вместо
81 | '#', но от этой практики стоит уйти.
82 | * При описании SQL в обычном тексте все операторы должны указываться в UPPER_CASE: `SELECT`;
83 | * Фрагменты кода вне обычного текста и любой связный код должен оформляться соответствующе:
84 |
85 | ```java
86 | /**
87 | * Something code
88 | */
89 | ```
90 |
91 | * Если возможно, в блоке кода должен быть указан язык для подсветки синтаксиса. Кроме случаев использования псевдокода;
92 | * При использовании SQL в блоке кода допустима запись в нижнем регистре. В т.ч. для операторов;
93 | * При использовании названий сущностей или методов на русском (в качестве примеров, для прозрачности условия
94 | практики и т.д.) используется курсив. При этом имена сущностей указываются с большой буквы, для методов
95 | указываются скобки: "...создайте сущность _Машина_", "... используйте _метод1()_".*
96 |
97 | > *По возможности этот подход стоит избегать, но он может быть актуален в первых уроках курса.
98 |
99 | ### Bold текст
100 |
101 | * Полужирным выделяются новые термины при их первом упоминании;
102 | * Опционально, термины могут выделяться полужирным второй раз в месте, где дается определение ранее упомянутому термину.
103 |
104 | ### Цитаты
105 |
106 | Использование цитат оправдано в следующих случаях:
107 |
108 | 1. Сноски, обозначенные через '\*'. При этом в цитате тоже указывается '\*'. Проверяйте, чтобы отображался именно
109 | указанный символ, а не символ ненумерованного списка;
110 | 2. NB (Nota bene) блоки. Форма записи следующая:
111 |
112 | > !NB: Какая-то информация.
113 |
114 | 3. Побочная информация, вроде отсылок к практике или примерам из опыта.
115 | 4. Футер с контактами
116 |
117 | В первых трех случаях цитаты уже используются в текущем оформлении, достаточно их перенести. Исключения возможны лишь
118 | в первых 30 уроках.
119 |
120 | ### Заключительные шаги
121 |
122 | После мержа вашего PR, проверьте, что в Road Map была скорректирована ссылка на урок - это будет ответственность
123 | ревьюера, но проверить за ним можете и вы:)
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/141/Tomcat. Installation and alternatives.md:
--------------------------------------------------------------------------------
1 | # Tomcat. Установка. Альтернативы
2 |
3 | В этой статье мы начнем знакомство с конечными инструментами, на которых в дальнейшем будем запускать серверные
4 | приложения - речь пойдет о контейнерах сервлетов. Так, мы кратко познакомимся с некоторыми из реализаций, а также
5 | установим наиболее популярный из них. Как и когда-то с СУБД, дальнейшие статьи будут связаны с конфигурацией и
6 | использованием сервера, который сегодня будет установлен.
7 |
8 | ## Обзор
9 |
10 | В современном Java-мире можно выделить три наиболее популярных имплементации контейнера сервлетов:
11 |
12 | 1. Apache Tomcat;
13 | 2. Jetty;
14 | 3. Undertow.
15 |
16 | Ниже чуть более подробно познакомимся с каждой из них и попытаемся сравнить.
17 |
18 | > На самом деле реальная ценность сравнительной характеристики в разрезе данного курса сомнительна - и
19 | > представителю целевой аудитории этой статью, и не-сеньор разработчику в принципе редко приходится задумываться о
20 | > выборе инструмента такого уровня - нет ни полномочий, ни знаний, ни достаточного опыта, чтобы сравнивать серверы с
21 | > прицелом на целевое приложение, которое будет на этом сервере работать.
22 | >
23 | > Поэтому своей задачей я вижу, в первую очередь, дать основные реализации и наиболее запоминающиеся характеристики
24 | > каждой из них, чтобы выстроить хоть какой-то ассоциативный ряд при словосочетании "контейнер сервлетов".
25 | >
26 | > Возможно, это поможет выиграть несколько очков на техническом собеседовании, что всегда ценно для начинающего
27 | > специалиста.
28 |
29 | ### Apache Tomcat
30 |
31 | Первый из представленных вариантов - Apache Tomcat (чаще просто Tomcat) - наиболее популярный инструмент, который мы и
32 | будем использовать далее. И популярность - его основной плюс. Он во многом менее гибок в настройке и почти во всем -
33 | наименее производительный из текущего списка, но зато крайне прост в установке и использовании. Кроме того, за счет
34 | огромной популярности можно быстро найти решения типовых проблем, что крайне важно для новичков.
35 |
36 | Также стоит отметить, что Tomcat является сервером по умолчанию для Spring Boot - одной из основных составляющих
37 | фреймворка Spring, с которым мы будем знакомиться в следующих разделах.
38 |
39 | Скорее всего, со временем и опытом у вас появятся собственные предпочтения и аргументы в пользу какого-либо из
40 | контейнера сервлетов или другой платформы для серверных приложений. Пока же - Tomcat лучший выбор для новичков.
41 |
42 | ### Jetty
43 |
44 | Легковесный контейнер сервлетов, более производительный, чем Tomcat, но намного менее популярный. Что является
45 | наиболее существенным недостатком на данном этапе. В целом, достаточно прост в конфигурации, в чем-то даже более
46 | дружелюбен, чем Tomcat. Но встретить его на реальном проекте - редкость.
47 |
48 | Яркой особенностью данного решения является то, что оно полностью написано на Java.
49 |
50 | ### Undertow
51 |
52 | Наиболее производительный из рассматриваемых сегодня контейнеров сервлетов. Известен, во многом, благодаря
53 | поддержке асинхронной обработки запросов. Строго говоря, такую возможность предоставляет и Tomcat
54 | (с определенной версии), и Jetty, но именно у Undertow это подчеркивается как конкурентное преимущество.
55 |
56 | Кроме того, характерной особенностью Undertow является то, что этот продукт тесно связан с Red Hat (ранее
57 | разрабатывался JBoss)*. Обе эти компании широко известны как производители ПО (вплоть до собственного дистрибутива
58 | Linux), в т.ч. продуктов, реализующих спецификации Java EE.
59 |
60 | > *Сам Red Hat был поглощен другим IT-гигантом - IBM.
61 |
62 | Так, JBoss в свое время разработал один из наиболее известных application server'ов - WildFly. Который, в свою
63 | очередь, использует Undertow в качестве контейнера сервлетов (и в более широком смысле - веб-сервера) по умолчанию.
64 |
65 | Несмотря на все вышесказанное, Undertow уступает по популярности Tomcat и Jetty. Кроме того, он менее дружелюбен в
66 | конфигурации.
67 |
68 | ## Установка Tomcat
69 |
70 | Установка Apache Tomcat возможна как посредством распаковки архива с дальнейшей конфигурацией приложения (для любой
71 | ОС), так и через специальную программу установщик (для Windows). Оба варианта достаточно просты, скачать можно здесь:
72 | [ссылка](https://tomcat.apache.org/download-10.cgi). Но вариант с установочным приложением выглядит более
73 | дружелюбным для новичков.
74 |
75 | Подробная инструкция кажется избыточной, все, что требуется:
76 |
77 | 1. В случае с установочником - лишь запустить exe-файл, в специальных окнах указать локацию JDK и директорию для
78 | установки самого Tomcat. Остальные пункты можно оставлять по умолчанию;
79 | 2. В случае с архивом - распаковать и следовать инструкции по установке и запуску, точную локацию самой инструкции
80 | можно найти в `README.md` внутри архива. Обычно - `RUNNING.txt`.
81 |
82 | Несколько нюансов при установке и первом запуске на Windows:
83 |
84 | - Не стоит располагать JDK в скрытой директории. Это особенно актуально, если JDK вы устанавливали через IDEA - по
85 | умолчанию JDK будут скачиваться в папку `${userHome}/.jdks`. Это может привести к тому, что Tomcat не сможет
86 | получить доступа к JDK;
87 | - Не стоит устанавливать Tomcat в каталоги вроде `Program Files`. На них могут стоять ограничения (скажем, только
88 | для Администратора), что тоже может затруднить дальнейший доступ к серверу;
89 | - При возникновении проблем с запуском стоит проверить содержимое лог-файлов. Их можно найти по
90 | адресу `${userHome}/.jdks/logs`. При проблемах с запуском сервера стоит в первую очередь проверять содержимое
91 | файла с `commons-daemon` в названии.
92 |
93 | После успешной установки и запуска сервера можно убедиться в успешности мероприятия. Достаточно открыть в браузере
94 | `http://localhost:8080/` (или другой порт, если вы заменили стандартный в процессе установки/конфигурации). Должна
95 | открыться страница, похожая на эту:
96 |
97 | 
98 |
99 | Если это произошло - поздравляю, установка и запуск прошли успешно.
100 |
101 | Если Tomcat не был добавлен в приложения с автозапуском, вы всегда можете стартовать его вручную через
102 | соответствующий `.exe`/`.bat`/`.sh` файл - в зависимости от ОС и предпочтительного способа запуска.
103 |
104 | #### На сегодня все!
105 |
106 | 
107 |
108 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
109 | >
110 | > Канал: https://t.me/ViamSupervadetVadens
111 | >
112 | > Мой тг: https://t.me/ironicMotherfucker
113 | >
114 | > **Дорогу осилит идущий!**
115 |
--------------------------------------------------------------------------------
/lessons/pet-projects/Pet project.md:
--------------------------------------------------------------------------------
1 | # Система распределения места в общежитиях
2 |
3 | Идея крупного пет-проекта существовала давно и время от времени на нее возникал запрос от участников канала. Кажется,
4 | пришло время предложить такой пет-проект. На данный момент нам вполне хватает знаний, чтобы подобный проект реализовать.
5 |
6 | На мой взгляд, более-менее правильная реализация данного проекта позволит добавлять в него новые возможности по мере
7 | изучения новых тем. В данном случае я говорю о подключении БД и реализации данного проекта в виде клиент-серверного
8 | приложения. Пока же проект предполагает работу через консоль и хранение данных в файлах.
9 |
10 | > Прежде чем приступите к чтению ТЗ: требования будут расширяться и дополняться по вашим вопросам/запросам. Написать
11 | > полное и корректное ТЗ даже для небольшого (как этот) проекта - задача нелегкая. Поэтому чем больше вопросов вы
12 | > зададите, тем точнее и понятнее будет описана ожидаемая функциональность проекта.
13 |
14 | 
15 |
16 | ## Требования
17 |
18 | Реализуйте систему распределения мест в студенческих общежитиях.
19 |
20 | Предусмотрите возможность:
21 |
22 | 1. [CRUD](https://ru.wikipedia.org/wiki/CRUD) для пользователей системы;
23 | 2. Ролевую модель пользователей, включая изменение прав для пользователей;
24 | 3. Разграничение доступа к данным для пользователей с различными ролями:
25 | - доступ ко всем данным _системы_;
26 | - доступ в рамках одного _университета_;
27 | - доступ в рамках одного _общежития_.
28 | 4. Авторизацию пользователей;
29 | 5. CRUD для сущностей _«университет»_, _«общежитие»_, _«комната»_, _«студент»_, включая реализацию реестров (просмотра
30 | списком) для этих сущностей;
31 | 6. Фильтрацию и сортировку данных. Учитывайте ограничения доступа в рамках роли при реализации;
32 | 7. Заселения и выселения студентов в (из) общежитие (-я), изменение плана заселения. Учитывайте принадлежность студентов
33 | и общежитий к различным университетам. Также учитывайте половую принадлежность студентов – в одной комнате могут жить
34 | студенты только одного пола;
35 | 8. Сбор статистики о количестве свободных мест в общежитиях, а также о количестве студентов, проживающих и не
36 | проживающих в общежитиях для каждого университета;
37 | 9. Актуализацию данных – студенты, окончившие обучение или отчисленные из университета, должны удаляться из системы как
38 | автоматически, так и по запросу пользователя. Учитывайте, что разные университеты могут иметь разную
39 | продолжительность обучения;
40 | 10. Хранение и актуализацию данных в файлах. 1 сущность – 1 файл;
41 | 11. Хранение данных пользователя в защищенном виде: хранение пароля допустимо только в виде хэша;
42 | 12. Валидация данных. Например, в комнате не может проживать больше людей, чем указано в ее максимальной вместимости;
43 | 13. Интерактивное консольное меню;
44 | 14. Генератор данных. Предусмотрите возможность создавать случайных студентов и комнаты общежития на основании
45 | предопределенного набора параметров. Генерация данных для остальных сущностей – на ваше усмотрение;
46 | 15. Логируйте действия пользователей. Лог должен быть записан в отдельный файл.
47 |
48 | ## Модель данных
49 |
50 | Вы можете создавать любые сущности с любым набором полей. Ниже представлены рекомендованные наборы полей для каждой
51 | сущности.
52 |
53 | ### Пользователь
54 |
55 | 1. ID
56 | 2. Логин
57 | 3. Хэш пароля
58 | 4. Роль
59 | 5. ФИО
60 |
61 | ### Университет
62 |
63 | 1. ID
64 | 2. Название
65 | 3. Длительность обучения
66 |
67 | ### Общежитие
68 |
69 | 1. ID
70 | 2. Номер
71 | 3. Количество комнат
72 | 4. Университет
73 | 5. Доступность для проживания
74 |
75 | ### Комната
76 |
77 | 1. ID
78 | 2. Номер
79 | 3. Общежитие
80 | 4. Вместимость
81 | 5. Доступность для проживания
82 | 6. Пол проживающих
83 |
84 | ### Студент
85 |
86 | 1. ID
87 | 2. ФИО
88 | 3. Пол
89 | 4. Университет
90 | 5. Общежитие
91 | 6. Комната
92 | 7. Год поступления
93 | 8. Дата отчисления
94 | 9. Проживает ли в общежитии
95 |
96 | ## Рекомендации по реализации
97 |
98 | 1. Декомпозируйте задачи. Проект не рассчитан на реализацию за вечер. Разбейте реализацию на подзадачи и выполняйте их;
99 | 2. Спроектируйте архитектуру вашего приложения заранее. Продумайте, какие основные пакеты и классы должны быть в вашем
100 | приложении, за что они должны отвечать. Некоторые примеры организации классов и их зон ответственности можно
101 | подсмотреть в [разборе](https://github.com/KFalcon2022/practical-tasks) крупных задач из практики;
102 | 3. Минимизируйте работу с файлами. Вполне допустимо, если чтение из файлов будет происходить при запуске программы/при
103 | первом обращении к данным, а запись – по завершению работы программы;
104 | 4. Помните, что пишете на Java, а Java – объектно-ориентированный язык. Многие вещи реализовать проще, если помнить о
105 | принципах ООП и паттернах проектирования. С последними мы, к сожалению, еще слабо знакомы;
106 | 5. Уточняйте модель данных. Как минимум один нюанс сейчас опущен осознанно, ряд других, вероятно, упущены из-за
107 | невнимательности автора;
108 | 6. Не стесняйтесь задавать вообще любые вопросы и уточнять непонятные/опущенные в описании нюансы. Требования к проекту
109 | будут дополняться и уточняться по мере поступления вопросов;
110 | 7. Вы так или иначе столкнетесь с необходимостью хранить информацию о том, какой пользователь ведет работу в системе в
111 | данный момент. Поскольку на данном этапе приложение однопоточное и мы не знакомы с более удобными инструментами для
112 | хранения данных активного пользователя - предлагаю задействовать под это отдельный класс-контекст, хранящий активного
113 | пользователя;
114 | 8. Ознакомьтесь с возможностями ветвления в _git_, а также слиянием веток (на данном этапе рекомендую _merge_).
115 | Выполняйте подзадачи (см. п.1) в отдельных ветках, которые потом вливайте в основную. Данные инструменты работы с
116 | _git_ еще не были затронуты в канале, но они могут облегчить написание вашего приложения уже сегодня. Как минимум,
117 | вам будет сложнее что-то безвозвратно сломать;
118 | 9. В целом, советую завести репозиторий на гитхабе для данного проекта и не стесняться добавлять меня в PR на этапе
119 | вливания новой подзадачи в основную ветку. Ревью - хороший источник роста для начинающих специалистов. А чем мельче
120 | PR, тем пристальнее ревью. Ревью готового проекта куда менее ценно, чем ревью подзадач.
121 |
122 | P.s. Если есть техпис или бизнес-аналитик, который готов помочь оформить требования к пет-проекту более качественно –
123 | пишите в ЛС.
124 |
125 | > Канал: https://t.me/ViamSupervadetVadens
126 | >
127 | > Мой тг: https://t.me/ironicMotherfucker
128 | >
129 | > **Дорогу осилит идущий!**
130 |
--------------------------------------------------------------------------------
/lessons/java-core/007/Methods. VarArgs. Overloading method. Recursion.md:
--------------------------------------------------------------------------------
1 | # Методы. Varargs. Перегрузка методов. Первое знакомство с рекурсией
2 |
3 | ## Varargs
4 |
5 | Те, кто вчера внимательно читал [статью](https://metanit.com/java/tutorial/2.16.php) о параметрах метода мог заметить
6 | блок «Параметры переменной длины». Также такой формат передачи параметров называется **varargs**.
7 |
8 | Заключается он в том, что в качестве последнего параметра метода мы можем указать массив в следующем виде:
9 |
10 | ```
11 | тип_данных... название_параметра
12 | ```
13 |
14 | Для чего такая форма записи нужна? Хорошим примером может быть `System.out.printf()`. Он принимает в себя базовую
15 | строку, в которой мы и указываем спецификаторы вроде `%s`, `%d`, а далее идет параметр в форме varargs, необходимый для
16 | того, чтобы передать значения, которые будут установлены вместо спецификаторов. Очевидно, что разработчик не знает,
17 | сколько спецификаторов будет указано, а значит, не знает, какое количество параметров будет передано.
18 |
19 | Следует запомнить синтаксис данной конструкции, а также то, что она может быть использована только как последний
20 | параметр метода.
21 |
22 | ## Перегрузка методов
23 |
24 | **Перегрузка методов** — механизм в Java (и ряде других ЯП), которая заключается в реализации методов с одинаковыми
25 | названиями, но разными параметрами и, соответственно, разной реализацией.
26 |
27 | Предлагаю ознакомиться со [статьей](https://metanit.com/java/tutorial/2.18.php).
28 |
29 | А также с видео:
30 | [](https://www.youtube.com/watch?v=OE6jUYt8O4Q)
31 |
32 | Что стоит отметить:
33 |
34 | * При перегрузке мы можем изменять тип возвращаемого значения;
35 | * Изменение возвращаемого значения без изменения параметров — **ошибка компиляции**, такой код работать не будет. Java
36 | не будет знать, какой метод использовать;
37 | * Не увлекайтесь перегрузкой без необходимости. Она нужна для обработки схожей логики, которая возможна при разных
38 | входных параметрах.
39 |
40 | Также в этом разделе предлагаю познакомиться с новым для нас термином: **сигнатура метода**.
41 |
42 | Сигнатура метода — это название метода и список передаваемых в него параметров. Например:
43 |
44 | ```java
45 | static void doSomething(int a, int b) {
46 | //...
47 | }
48 | ```
49 |
50 | Здесь сигнатурой является `doSomething(int a, int b)`.
51 |
52 | Этот термин мы будем еще раз разбирать, когда познакомимся с **переопределением**, но впервые рассмотрим его сегодня.
53 |
54 | Стоит отметить, что тип возвращаемого значения не входит в сигнатуру. При перегрузке сигнатура метода изменяется: при
55 | одинаковых названиях мы передаем разные параметры.
56 |
57 | В дальнейшем, именно различие или совпадения сигнатуры помогут нам различать перегрузку и переопределение — очень
58 | популярный вопрос на собеседовании junior-специалистов.
59 |
60 | ## Рекурсия
61 |
62 | **Рекурсия** - определение, описание, изображение какого-либо объекта или процесса внутри самого этого объекта или
63 | процесса.
64 |
65 | Рекурсию у объектов мы разберем позже, сегодня остановимся на рекурсии у методов. Несмотря на громоздкое определение,
66 | понять принцип рекурсии просто.
67 |
68 | **Рекурсивный метод** - метод, который вызывает сам себя.
69 |
70 | Однако, предлагаем сформировать первое впечатление на основании [статьи](https://metanit.com/java/tutorial/2.8.php)
71 |
72 | Что стоит отметить:
73 |
74 | * Любой рекурсивный алгоритм можно представить **итеративно** — с помощью циклов;
75 | * Какие-то алгоритмы проще реализовать через рекурсию (QuickSort, обход дерева), какие-то — через циклы (большинство
76 | математических операций, включая факториал);
77 | * Использовать рекурсию нужно с осторожностью — она гораздо сильнее нагружает процессор, нежели использование циклов.
78 | Отсутствие корректного выхода из рекурсии приведет к ошибке JVM.
79 |
80 | Рекурсии не надо бояться, это достаточно простой механизм. Но рекурсивные алгоритмы могут быть сложными для
81 | восприятия — нашему мозгу тяжело их вообразить. Главная задача этого пункта — объяснить, что это нормально, потому
82 | что наш мозг — не компьютер.
83 |
84 | Есть ситуации, когда рекурсия полезна и упрощает логику, есть обратные — когда использование рекурсии делает код
85 | сложнее, а его выполнение происходит медленнее. Из чего следует вывод: если вы не понимаете, как будет работать ваш
86 | рекурсивный алгоритм — не стоит его использовать, лучше перепишите через циклы.
87 |
88 | #### С теорией на сегодня все!
89 |
90 | 
91 |
92 | Переходим к практике:
93 |
94 | ## Задача 1:
95 |
96 | Написать программу, которая объединяет любое количество строк, объединяя их через пробел. Реализацию конкатенации строк
97 | вынести в отдельный метод.
98 |
99 | ## Задача 2:
100 |
101 | Реализовать методы «вычисления суммы» для всех примитивных типов, кроме void. Возвращать:
102 |
103 | * Для числовых типов — тот же тип. Даже если это ведет к потере точности. При угрозе потери данных — выводить сообщение
104 | в консоль и возвращать текущий результат (для `byte`, `short`, `int`);
105 | * Для `boolean` — определение истинности всех переданных параметров, принимая то, что их стоит объединять через
106 | логическое `И`;
107 | * Для `char` — строку, полученную в результате конкатенации всех переданных параметров.
108 |
109 | Количество параметров может быть любым. Используйте перегрузку — у всех методов должны быть одинаковые названия.
110 |
111 | > Примечание: это задача без вариантов, методы для всех типов должны быть реализованы в одной программе.
112 |
113 | ## Задача 3:
114 |
115 | Вычислите факториал введенного с клавиатуры целого числа, используя рекурсивный алгоритм.
116 |
117 | ## Задача 4:
118 |
119 | Вычислите результат выражения, используя рекурсивный алгоритм. n — число, введенное с клавиатуры. Для N < 1 — вывести
120 | соответствующее сообщение в консоль и завершить выполнение программы.
121 | 
122 |
123 | ## Задача 5 (*):
124 |
125 | Вычислить и записать в массив первые 10 простых чисел.
126 |
127 | **Простое число** – положительное целое число, которое делится без остатка лишь на себя и на 1. 1 не является простым
128 | числом.
129 |
130 | Вывести в консоль сумму всех элементов полученного массива. Нахождение простых чисел и вычисление суммы реализовать,
131 | используя рекурсивные методы.
132 |
133 | **Разбор практики для этого урока**:
134 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson7_varargs_overloading)
135 |
136 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
137 | >
138 | > Канал: https://t.me/ViamSupervadetVadens
139 | >
140 | > Мой тг: https://t.me/ironicMotherfucker
141 | >
142 | > **Дорогу осилит идущий!**
143 |
--------------------------------------------------------------------------------
/lessons/java-core/021/Immutable objects.md:
--------------------------------------------------------------------------------
1 | # Неизменяемые объекты
2 |
3 | Скоро мы будем знакомиться более подробно с классом `String` и его альтернативами, а также с классами-обертками над
4 | примитивными типами.
5 |
6 | Для этого нам стоит разобраться с понятием неизменяемого объекта и актуальностью его применения.
7 |
8 | ## Изменяемые и неизменяемые объекты
9 |
10 | В большинстве ООП языков, любой объект можно отнести к одной из двух категорий:
11 |
12 | - **Изменяемый** – **mutable**;
13 | - **Неизменяемый** – **immutable**. В рамках профессионального общения вы можете услышать вариант **«имьютабельный»**.
14 |
15 | Основным признаком изменяемости объекта можно считать возможность изменить значения его полей после инициализации. По
16 | сути, если у вашего объекта есть хоть один сеттер или поле, которое не помечено `final` или имеет модификатор доступа,
17 | отличный от `private` – он однозначно изменяем.
18 |
19 | Изменяемыми являются абсолютное большинство классов-сущностей, что логично. Какой смысл от объекта типа _Счетчик_,
20 | если мы не можем изменить его значение?
21 |
22 | Неизменяемыми же часто делают классы бизнес-логики (по крайней мере, в современном Java-мире), иногда – классы-сущности.
23 | Кроме того, ряд базовых классов Java являются immutable: `String`, `Integer`, `Double`, `Character` и другие классы
24 | обертки.
25 |
26 | ## Зачем делать объект неизменяемым?
27 |
28 | Причины могут быть разными, но почти всегда сводятся к одному: изменение состояния объекта в процессе его жизни может
29 | привести к нежелательным изменениям поведения.
30 |
31 | Вспоминая задачу с `CounterAggregation` ([Урок 12](https://github.com/KFalcon2022/CounterAggregation)), представьте,
32 | что ваш массив в объекте класса `AggregationService` был изменен на другой, содержащий другие элементы. Не самый
33 | удачный пример, но даже в нем логика работы могла оказаться нарушена. Например, потому что вы не смогли найти счетчик,
34 | который точно туда добавляли. Или хуже – полю с массивом присвоили `null` – тогда практически любое обращение к методам
35 | `AggregationService` порождало бы исключение.
36 |
37 | Итак, как же гарантировать неизменяемость объекта в Java:
38 |
39 | 1. Класс должен быть `final`. Безусловно, это не влияет на изменяемость полей. Но для не финализированного класса нет
40 | гарантии, что в переменной этого типа не окажется записан объект класса-наследника с отличающейся логикой. Это
41 | правило выполняется далеко не всегда (особенно, для классов бизнес-логики), но о нем обязательно захотят услышать на
42 | собеседовании;
43 | 2. Все поля должны быть помечены `private final`. Это гарантирует неизменность примитивных полей и ссылок для полей
44 | ссылочных типов;
45 | 3. Инициализация полей должна производиться в конструкторе. Это вытекает из того, что поля помечены как `final`;
46 | 4. Отсутствие сеттеров. В целом, они и так бесполезны, если поля помечены `final`, но не всем это может быть
47 | очевидно;
48 | 5. Геттеры возвращают только примитивные типы или копии объектов, если геттер написан для поля ссылочного типа. Это
49 | связано с тем, что `final` поле гарантирует неизменность ссылки. Но никак не влияет на возможность изменить поля
50 | объекта, который по этой ссылке доступен.
51 |
52 | Неизменяемые объекты, кроме большей предсказуемости их поведения, в сравнении с изменяемыми, имеют и другие плюсы.
53 |
54 | Во-первых, их удобно использовать как идентификаторы. Скажем, объекты класса _Человек_ могут иметь массу изменяемых
55 | параметров: семейный статус, количество детей, ~~половая принадлежность~~… В общем-то, большинство полей, которыми можно
56 | охарактеризовать человека, могут изменить свое значение.
57 |
58 | Но если нам нужно найти человека среди множества других людей (скажем, в массиве) – нам понадобятся неизменные поля. В
59 | каких-то системах это может быть одно поле: например, уникальный номер паспорта или ИНН. В других системах это может
60 | быть несколько параметров. Скажем, дата и место рождения, ФИО при рождении. В таком случае может быть полезно вынести
61 | неизменяемые поля в отдельный класс, объекты которого и использовать как идентификатор*.
62 |
63 | > *К сожалению, пример вышел несколько натянутым, поскольку мы еще не знакомы с некоторыми механиками языка, в которых
64 | > это может быть полезно.
65 |
66 | Во-вторых, неизменяемые объекты можно переиспользовать. Например, работая с классом _Машина_ мы можем иметь набор
67 | изменяемых параметров для каждого конкретного объекта машины. Цвет, дата последнего прохождения ТО, наличие тонировки,
68 | ~~работоспособность поворотников~~… Но, при этом, технические характеристики будут неизменны для каждой модели. В таком
69 | случае может быть полезным вынести их в отдельный класс и создавать объекты характеристик не для каждой машины, а для
70 | каждой модели (очевидно, что количество моделей автомобилей намного меньше, чем самих автомобилей). Сама машина будет
71 | лишь иметь поле типа «технические характеристики», причем все машины одной модели будут содержать в этом поле ссылку на
72 | один и тот же объект. Такой подход может сильно сэкономить память.
73 |
74 | > **!NB**: если вы предполагаете использование объектов класса в качестве идентификатора (никогда не используйте в этих
75 | > целях изменяемые объекты) – подумайте о том, чтобы вынести хэшкод такого объекта в отдельное поле, возможно, его даже
76 | > стоит сделать константой. Это может помочь с ускорением поиска по массиву (в более широком смысле – коллекции) таких
77 | > объектов.
78 |
79 | ## В качестве итога
80 |
81 | **Immutable-объекты** – очень удобный инструмент в достаточно широком диапазоне задач. Не все случаи применения мы можем
82 | рассмотреть сейчас в силу недостатка знаний, но даже озвученные примеры, на мой взгляд, являются убедительной
83 | демонстрацией его полезности.
84 |
85 | Выше даны классические для Java правила достижения имьютабельности объекта. Не все из них и не всегда применяются в
86 | полной мере, все, как обычно, зависит от специфики конкретной задачи. На данном этапе рекомендую обратить внимание
87 | именно на имьютабельность для классов-сущностей, с классами логики все немного сложнее, но с этим мы будем разбираться
88 | позже.
89 |
90 | #### С теорией на сегодня все!
91 |
92 | 
93 |
94 | Переходим к практике:
95 |
96 | ## Задача:
97 |
98 | Реализуйте задачу из [урока 19](https://github.com/KFalcon2022/lessons/blob/master/lessons/java-core/019/Object%20methods.md#%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0).
99 |
100 | На свое усмотрение, вынесите неизменяемые поля, используемые для идентификации и поиска машины в отдельный immutable
101 | класс или сделайте весь класс _Машина_ неизменяемым. Правильный выбор зависит от набора полей, который существует в
102 | вашей текущей реализации класса _Машина_.
103 |
104 | **Разбор практики для этого урока**:
105 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson21_immutable_object)
106 |
107 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
108 | >
109 | > Канал: https://t.me/ViamSupervadetVadens
110 | >
111 | > Мой тг: https://t.me/ironicMotherfucker
112 | >
113 | > **Дорогу осилит идущий!**
114 |
--------------------------------------------------------------------------------
/lessons/java-core/014/Polymorphism. Overriding method. Types of polymorphism.md:
--------------------------------------------------------------------------------
1 | # Полиморфизм. Переопределение методов. Виды полиморфизма и связывание
2 |
3 | ## Понятие полиморфизма
4 |
5 | **Полиморфизм** в максимально широком смысле — способность функции (метода) обрабатывать данные (параметры) разных
6 | типов.
7 |
8 | В такой формулировке это не что-то, характерное только для ООП. С одной из реализаций полиморфизма мы уже
9 | познакомились — это перегрузка. Перегрузка возможна и в процедурных языках. Например, в C или Pascal.
10 |
11 | В контексте ООП-парадигмы, полиморфизм — возможность реализации различного поведения в методах с одинаковой сигнатурой
12 | (сигнатура — название и параметры метода).
13 |
14 | Мы не можем реализовать два метода с одинаковой сигнатурой в одном классе. Зато можем задать одну реализацию в
15 | суперклассе (или не задавать вовсе, но с этим мы познакомимся позже), а в классах-наследниках **переопределить**
16 | поведение так, чтобы каждый наследник при вызове метода делал что-то свое.
17 |
18 | ## Переопределение методов
19 |
20 | Постараемся разобраться на примере. Вспоминая одну из задач предыдущего урока, возьмем суперкласс `Animal` и два его
21 | наследника — `Cat` и `Dog`. Пусть у класса `Animal` будет метод `sound()`, выводящий в консоль звуки, которые «говорит»
22 | животное. Поскольку разные животные «говорят» по-разному, определим в `Animal` следующую реализацию:
23 |
24 | ```java
25 | public class Animal {
26 | protected void sound() {
27 | System.out.println();
28 | }
29 | }
30 | ```
31 |
32 | Таким образом, некое животное не издает звук.
33 |
34 | И определим два наследника, которые говорят `meow` и `woof` соответственно:
35 |
36 | ```java
37 | public class Cat extends Animal {
38 | public void sound() {
39 | System.out.println("meow");
40 | }
41 | }
42 |
43 | public class Dog extends Animal {
44 | public void sound() {
45 | System.out.println("woof");
46 | }
47 | }
48 | ```
49 |
50 | Что характерно, теперь даже присвоив объект кота или собаки переменной типа животное, при вызове метода `sound()` все
51 | равно будет использоваться реализация, определенная в реальном классе объекта:
52 |
53 | ```java
54 | Animal cat = new Cat();
55 | Animal dog = new Dog();
56 |
57 | cat.sound();
58 | dog.sound();
59 | ```
60 |
61 | Вывод в консоль:
62 |
63 | ```
64 | meow
65 | woof
66 | ```
67 |
68 | Подчеркнем ряд деталей, характерных для переопределения. Также посмотрим, что можно менять в методе, переопределяя его,
69 | а что — нет:
70 |
71 | - Не обязательно (с т.з. Java), но рекомендуется над переопределяемыми методами использовать **аннотацию** `@Override`.
72 | Она указывает, что метод — переопределение метода суперкласса и проверяет совпадение сигнатур. С аннотациями мы
73 | познакомимся позже, но конкретно эту предлагаю начать использовать уже сейчас. Класс `Dog` с ней выглядит так:
74 |
75 | ```java
76 | public class Dog extends Animal {
77 | @Override
78 | public void sound() {
79 | System.out.println("woof");
80 | }
81 | }
82 | ```
83 |
84 | - При переопределении мы можем изменять модификатор доступа метода. Но только на расширение:
85 | `package-private` → `protected` → `public`;
86 | - Можно изменять возвращаемый тип. Но только сужая его: `Animal` → `Cat`;
87 | - Можно изменять название (не тип!) параметров в переопределенном методе;
88 | - Невозможно переопределить приватный метод;
89 | - Метод класса можно пометить как `final` — в таком случае его будет нельзя переопределить в наследниках;
90 | - Невозможно переопределить static-метод. Мы можем в классе-наследнике создать метод с той же сигнатурой, но это все
91 | равно будет перегрузкой, поскольку статические методы относятся к конкретному классу, а не его объектам. И при
92 | апкастинге будет вызываться метод того класса, который заявлен как тип данных переменной. Если static-метод не
93 | перегрузить — будет использоваться та же реализация, что и в суперклассе.
94 | - Использовать аннотацию `@Override` над статическим методом тоже не удастся.
95 |
96 | Также есть некоторые особенности с переопределением методов и исключениями, но с этим мы познакомимся в теме
97 | **Исключения**.
98 |
99 | ## Виды полиморфизма и связывание
100 |
101 | Этот раздел будет исключительно ознакомительный. Кому-то он поможет структурировать знания, кого-то может спасти на
102 | собеседовании.
103 |
104 | Итак, что такое **связывание**?
105 |
106 | ~~Хорошо связанный объект в предварительных ласках не нуждается~~. Связывание — механизм, соотносящий вызов метода в
107 | коде и реализацию этого метода. Также этот механизм иногда называют **привязкой**. Связывание можно разделить на два
108 | типа:
109 |
110 | 1. **Раннее связывание (статическая привязка)** — связывание на этапе компиляции кода. Т.е. какая реализация метода
111 | будет вызываться понятно еще до запуска. Это характерно для статических методов, поскольку их нельзя переопределить.
112 | В более широком смысле, сюда относится выбор реализации у перегруженных методов;
113 | 2. **Позднее связывание (динамическая привязка)** — связывание на **этапе выполнения** (он же **Runtime**). Это
114 | характерно для переопределенных методов. Вызвано это тем, что мы не всегда можем сказать, какая реализация будет
115 | использована, поскольку не всегда знаем какой тип объекта будет присвоен переменной, типизированной как суперкласс.
116 |
117 | Возвращаясь к полиморфизму, его тоже можно классифицировать:
118 |
119 | 1. **Статический** (все та же перегрузка);
120 | 2. **Динамический** (переопределение);
121 | 3. **Параметрический**. С ним мы подробнее познакомимся позже. На этом виде полиморфизма основаны **обобщенные типы
122 | (generic'и)** и, как следствие — **коллекции**. На данном этапе отметим для себя, что такой тип полиморфизма
123 | существует.
124 |
125 | #### С теорией на сегодня все!
126 |
127 | 
128 |
129 | Переходим к практике:
130 |
131 | ## Задача 1:
132 |
133 | Реализуйте класс «Правильная фигура». Для него создайте классы-наследники `Треугольник` и `Квадрат`.
134 |
135 | Пользователь должен иметь возможность ввести длину стороны и выбрать тип фигуры. Программа должна нарисовать в консоли
136 | выбранную пользователем фигуру, используя символы `'-'`, `'|'`, `'/'`, `'\'`.
137 |
138 | Обратите внимание, символ `'\'` в Java необходимо экранировать: `'\\'.`
139 |
140 | ## Задача 2:
141 |
142 | Используя новые знания, упростите реализацию задачи 2 из
143 | [предыдущего урока](https://github.com/KFalcon2022/lessons/blob/master/lessons/java-core/013/Inheritance.%20Keywords%20extends%20and%20super.%20Access%20modifier%20protected.md).
144 | Допустимо использовать метод `sound()`, вместо `woof()`, `meow()` и `moo()`.
145 | Метод `sound()` допустимо сделать публичным.
146 |
147 | Использовать отдельное поле для хранения выводимой строки — недопустимо:)
148 |
149 | > Примечание: не забывайте об использовании пакетов. Название продуктов (пакет 3-го уровня) для задач текущего урока
150 | > предлагаю выбрать самостоятельно.
151 |
152 | **Разбор практики для этого урока**:
153 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson14_polymorphism)
154 |
155 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
156 | >
157 | > Канал: https://t.me/ViamSupervadetVadens
158 | >
159 | > Мой тг: https://t.me/ironicMotherfucker
160 | >
161 | > **Дорогу осилит идущий!**
162 |
--------------------------------------------------------------------------------
/lessons/oop/011/OOP. Introduction.md:
--------------------------------------------------------------------------------
1 | # ООП. Первое знакомство. Понятие абстракции. Виды отношений между объектами
2 |
3 | ## Понятие ООП и парадигмы программирования
4 |
5 | **ООП** – **объектно-ориентированное программирование** – одна из наиболее популярных **парадигм** (или **методологий**)
6 | программирования, основанная на идее, что любую сущность можно представить в виде объекта (а значит и шаблонизировать в
7 | виде класса, если смотреть на реализацию в Java), а любую **информационную систему** (любое **программное обеспечение**)
8 | можно представить как взаимодействие различных объектов.
9 |
10 | Нужно понимать, что ООП – не единственная парадигма программирования. И даже не единственная в Java. Так, например,
11 | популярная ранее парадигма **процедурного программирования** (например, используемая C или Pascal) может, с
12 | определенными допущениями, использоваться в Java. Например, в темах, посвященных базовым синтаксическим конструкциям в
13 | Java, наш код можно, в какой-то степени, считать процедурным.
14 |
15 | Есть и парадигмы, которые не противоречат ООП и могут применяться совместно с ним. Например, **функциональное
16 | программирование**. Эта концепция вполне применяется в Java, и мы еще разберемся с ней в дальнейших уроках.
17 |
18 | Однако, постараемся немного ближе познакомиться с ООП.
19 |
20 | Кроме самого определения, ООП характеризуется определенными принципами: **наследование**, **инкапсуляция**,
21 | **полиморфизм**. Каждому из них мы посвятим по уроку и будем часто обращаться к ним в дальнейшем.
22 |
23 | Кроме того, в ООП есть такой основополагающий инструмент как **абстракция**. Вопрос о том, является ли абстракция
24 | принципом ООП – очень дискуссионный, но это не умаляет ее значения. Подробнее в следующем подразделе.
25 |
26 | ## Абстракция
27 |
28 | Абстракция, в каком-то смысле, схожа с [бритвой Оккама](https://ru.wikipedia.org/wiki/Бритва_Оккама).
29 |
30 | Основное назначение абстракции – описать реальный объект минимумом характеристик (полей). Так, для описания объекта мы
31 | должны использовать лишь те характеристики, которые важны в рамках нашей информационной системы.
32 |
33 | Поскольку объекты в ООП претендуют на отображение объектов реального мира, количество характеристик у объекта может быть
34 | очень большим. Разберем на примере ноутбука.
35 |
36 | Ноутбук можно охарактеризовать по цвету и материалу корпуса, цене, техническим характеристикам (объем жесткого диска и
37 | оперативной памяти, диагональ экрана), годом выпуска, гарантийным сроком, и т.д.
38 |
39 | Если мы разрабатываем **ИС** (информационную систему) для условного конструкторского бюро, для нас будут важны
40 | технические характеристики ноутбука, материал корпуса и прочие данные, которые необходимы для проектирования модели. При
41 | этом его цена, год выпуска и цвет корпуса либо не имеют значения, либо важны в меньшей степени, нежели остальные
42 | характеристики.
43 |
44 | Если же наша ИС предназначена для магазина техники, то цена, цвет, год выпуска и гарантийный срок будут иметь куда
45 | большее значение. Технические характеристики также будут важны, но в куда меньшей детализации, нежели в ИС для
46 | конструкторского бюро. А ряд характеристик, важных в рамках разработки модели, вообще не будет иметь значения для
47 | продажи этой модели.
48 |
49 | Таким образом, задача программиста в данной ситуации – определить и описать набор характеристик, важных в соответствии с
50 | задачами конкретной ИС. Добавление излишних характеристик может как оказаться избыточным, так и привести к
51 | неоправданному усложнению логики системы, что затруднит ее разработку, использование и поддержку.
52 |
53 | В качестве вывода: абстракция (в рамках описанного определения) не имеет какой-то синтаксической обертки на уровне
54 | языка. Но это один из ключевых принципов проектирования ПО, успешность применения которого критична для разработки
55 | системы и, во многом, именно умение использовать абстракцию может характеризовать хорошего разработчика.
56 |
57 | ## Виды отношений между объектами
58 |
59 | Как было сказано выше, в рамках ООП мы стараемся каждую систему описать как взаимодействие различных объектов. Именно
60 | способы взаимодействия мы и обсудим в этом подразделе.
61 |
62 | Ранее мы писали достаточно маленькие объемы кода и логики. Способы взаимодействия классов и объектов не могли оказать
63 | серьезного влияния на наши программы, просто потому что программы были очень маленькими. Однако, чем больше будут
64 | программы, которые мы будем писать, тем более критичным будет осознанность применения тех или иных видов отношения между
65 | объектами внутри этих программ.
66 |
67 | Этот подраздел может показаться сложным на данном этапе, поэтому советую время от времени возвращаться к нему, с
68 | практикой использования ООП будет постепенно улучшаться и понимание видов отношений.
69 |
70 | Отношения между классами, а, как следствие, и объектами, можно разбить на две группы:
71 |
72 | 1. **is-a**. Объект является частным случаем – реализацией – другого объекта. Например: утка - реализация (частный
73 | случай) птицы;
74 | 2. **has-a**. Объект имеет (содержит) в себе другой объект. Иными словами, один объект является частью другого.
75 |
76 | С отношениями is-a мы познакомимся полноценно в ближайших уроках, поскольку еще не знакомы с синтаксисом и понятиями,
77 | которые позволили бы закрепить наше понимание.
78 |
79 | А отношения has-a рассмотрим подробнее уже сейчас. Иначе это отношение можно назвать как **ассоциация**.
80 |
81 | Ассоциация на уровне Java будет означать, что один объект ассоциирован (представлен в виде поля) в рамках другого
82 | объекта. Двигатель может быть полем машины, классный руководитель – полем объекта _УчебныйКласс_ в школе.
83 |
84 | Ассоциацию можно разделить на следующие виды:
85 |
86 | * **Агрегация**;
87 | * **Композиция**.
88 |
89 | Агрегация – объект может существовать сам по себе, не только составной частью другого объекта. В данном случае, имеется
90 | ввиду именно целесообразность существования объекта вне другого, а не физическая возможность его создать. В качестве
91 | примера рассмотрим людей (пассажиров) в автомобиле. Пассажиры, определенно, имеют отношение к автомобилю. Но при этом
92 | эти люди вполне существуют вне автомобиля.
93 |
94 | Композиция – объект не существует, кроме как составная часть другого объекта. Опять же, речь о целесообразности
95 | существования. Например, ячейка в рамках листа в Excel. Технически, на уровне кодовой базы, вероятно, существует способ
96 | создания ячейки вне привязки к листу документа. Но такая ячейка в вакууме не имеет смысла.
97 |
98 | Как способ определения типа отношения в коде можно использовать следующее правило: разница между композицией и
99 | агрегацией заключается в том, что в случае композиции целое явно контролирует время жизни своей составной части (часть
100 | не существует без целого), а в случае агрегации целое хоть и содержит свою составную часть, время их жизни не
101 | связано (например, составная часть передается через параметры конструктора).
102 |
103 | Первое знакомство с видами отношений часто порождает больше вопросов, чем дает ответов. Однако я искренне убежден, что
104 | этот материал стоит давать как можно раньше, чтобы со временем использование различных типов отношений становилось все
105 | более осознанным. Понятие отношений не имеет однозначной связи с синтаксисом в Java (хотя кто-то может иметь иное
106 | мнение). И различные, с точки зрения логики, отношения можно реализовать одними и теми же инструментами языка. Но, тем
107 | не менее, разработчику стоит понимать, какой тип отношений он использует в той или иной логике.
108 |
109 | #### На сегодня все!
110 |
111 | 
112 |
113 | С теорией на сегодня все. Поскольку урок больше ознакомительный, сегодня без практики. Дадим отстающим шанс нагнать:)
114 |
115 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
116 | >
117 | > Канал: https://t.me/ViamSupervadetVadens
118 | >
119 | > Мой тг: https://t.me/ironicMotherfucker
120 | >
121 | > **Дорогу осилит идущий!**
122 |
--------------------------------------------------------------------------------
/lessons/java-core/016/Abstract classes and interfaces.md:
--------------------------------------------------------------------------------
1 | # Абстрактные классы и интерфейсы
2 |
3 | ## Абстрактные классы и ключевое слово abstract
4 |
5 | Знакомство с данной темой предлагаю начать со [статьи](https://metanit.com/java/tutorial/3.6.php).
6 |
7 | В ней можно найти базовые примеры использования и самих **абстрактных классов**, и ключевого слова `abstract`. Ниже мы
8 | рассмотрим ряд особенностей, о которых следует помнить, чтобы использовать механизм абстрактных классов эффективно.
9 |
10 | Немного об `abstract`:
11 |
12 | - `abstract` применим лишь к классам и методам. Абстрактных полей или конструкторов не бывает;
13 | - Использование `abstract` в отношении класса говорит о том, что создать объекты этого класса невозможно. Лишь объекты
14 | его наследников;
15 | - `abstract` перед классом не обязует создавать абстрактных методов в нем. Другой вопрос, насколько имеет смысл
16 | абстрактный класс без абстрактных методов;
17 | - Технически, абстрактный класс может быть наследником не абстрактного (не говоря об `Object`). Но это показатель плохо
18 | спроектированной системы;
19 | - **Абстрактных методов** в абстрактном классе может быть неограниченное количество;
20 | - Если наследник не переопределяет все абстрактные методы предка — наследник тоже должен быть абстрактным классом.
21 |
22 | А также о концептуальных нюансах:
23 |
24 | - Стоит ли делать класс абстрактным — зависит от конкретной ситуации. Одни и те же сущности могут быть по-разному
25 | представлены в разных информационных системах, это зависит лишь от того, как спроектирована система. Если вспомним
26 | задачу 2 из темы
27 | [наследование](https://github.com/KFalcon2022/lessons/blob/master/lessons/java-core/013/Inheritance.%20Keywords%20extends%20and%20super.%20Access%20modifier%20protected.md),
28 | кажется логичным сделать `Animal` абстрактным классом. Однако в задаче 1 из того же урока такой необходимости нет;
29 | - Абстрактные классы редко применяются к классам-сущностям. Еще реже в таких случаях используются абстрактные методы.
30 |
31 | К абстрактным классам мы еще будем возвращаться, чтобы изучить их сферу применения глубже. На сегодня ограничим наше
32 | знакомство синтаксисом и теми особенностями, что изложены выше.
33 |
34 | ## Интерфейсы
35 |
36 | Рекомендую ознакомиться со [статьей](https://metanit.com/java/tutorial/3.7.php).
37 |
38 | Она достаточно объемна, но ее стоит изучить досконально, кроме, пожалуй, раздела **Вложенные интерфейсы**.
39 |
40 | Для того чтобы уложить интерфейсы в своей картине мира, стоит понять, что интерфейсы представляют собой бОльшую
41 | абстракцию, чем абстрактные классы.
42 |
43 | Абстрактный класс, концептуально - это полноценная сущность (реального мира), но слишком широкая, чтобы определить ее
44 | поведение однозначно. При этом достаточно узкая, чтобы неоднозначное поведение можно было декларировать (посредством
45 | абстрактных методов). В конечном итоге, наследники должны лишь уточнить особенности поведения, реализовав
46 | (переопределив) абстрактные методы сущности. Крайне редко (и почти всегда - ошибочно) у наследника появляются
47 | собственные публичные методы, которые отсутствовали в абстрактном классе.
48 |
49 | Интерфейсы, в свою очередь, предназначены лишь для **декларации** поведения. При этом само поведение может быть
50 | настолько общим, что конечные его реализации вообще непредсказуемы. Достаточно часто методами интерфейса бывает что-то
51 | вроде `process()` или `handle()`. И реализации этих методов в разных классах могут не иметь вообще ничего общего, кроме
52 | сигнатуры. Проводя аналогии, интерфейс может быть схож с объявлением переменной, а его реализации - с инициализацией
53 | переменной. Только в данном случае мы будем объявлять и инициализировать некую логику (поведение).
54 |
55 | Именно так дело обстоит с точки зрения концепции абстрактных классов и интерфейсов в Java. На практике область
56 | применения интерфейсов шире:
57 |
58 | - Интерфейс может быть декларацией поведения для абстрактного класса. И тогда иерархию наследования можно рассматривать
59 | как `interface` → `abstract class` → `subclass`. Такой сценарий можно встретить достаточно часто в классах
60 | бизнес-логики, реже — в классах сущностей;
61 | - Интерфейс может быть просто **маркером**, демонстрирующим, что конечные классы имеют определенные особенности или
62 | возможности. Методов в таком интерфейсе вообще не будет. В дальнейшем мы встретим несколько примеров этого в Java.
63 | Возможно, и сами реализуем подобный механизм в задаче, где это необходимо;
64 | - Интерфейсы бывают **функциональными**. С этим мы будем разбираться отдельно в контексте функционального
65 | программирования в Java, точнее, разбирая роль **лямбда-выражений** в нем;
66 | - Иногда интерфейсы необходимы, чтобы реализовать множественное наследование. Напомню, мы не можем наследоваться от
67 | нескольких классов. А реализовывать несколько интерфейсов (в т.ч. одновременно с наследованием класса) — можем. Такое
68 | стало возможно после появления **дефолтных реализаций** методов интерфейсов в Java 8. Почти всегда такое применение
69 | будет ошибкой проектирования, но есть вероятность, что вы с этим столкнетесь в будущем;
70 | - Иногда задача интерфейса — действительно указать на поведение в прямом смысле. Чаще всего, это разного рода
71 | обработчики (кнопок, сообщений, чего угодно). В таком случае каждая реализация интерфейса будет обрабатывать свой тип
72 | кнопок/сообщений/чего угодно. Достаточно популярный механизм вне зависимости от направления разработки. Такое можно
73 | встретить и в desktop, и в mobile, и в backend. Вероятно, мы рассмотрим этот подход позже, в контексте паттернов
74 | проектирования.
75 |
76 | Как видите, сфера применения интерфейсов очень широка — намного шире, чем у абстрактных классов. Однако стоит
77 | подчеркнуть разницу между ними. Со временем это может помочь с выбором инструмента для конкретной задачи:
78 |
79 | - Абстрактный класс – это сущность, интерфейс – это контракт (декларация поведения). Сущность расширяется, контракт
80 | реализовывается. Расширить можно только один класс, реализовать - несколько интерфейсов;
81 | - Абстрактный класс – это класс, у которого не реализован один или несколько методов;
82 | - Интерфейс – не может содержать реализаций методов (до Java 8);
83 | - Методы интерфейса по умолчанию `public` (с Java 9 интерфейс может содержать и `private` методы). Методы абстрактного
84 | класса могут иметь любые модификаторы доступа;
85 | - Поля интерфейса всегда `public static final`, пусть явно это и не указывается. Поля абстрактного класса – любые.
86 |
87 | Также стоит помнить, что если ваш класс реализует не все методы интерфейса, такой класс должен быть абстрактным. При
88 | условии, что методы интерфейса не имеют дефолтной реализации.
89 |
90 | Кроме того, необходимо отметить, что если ваш класс реализует интерфейс и расширяет класс, а интерфейс и класс содержат
91 | метод(ы) с одинаковой сигнатурой, но разной реализацией, то наследник по умолчанию будет использовать реализацию
92 | абстрактного класса. Однако такие ситуации являются нежелательными.
93 |
94 | Тема абстрактных классов и интерфейсов крайне важна для Java-разработки. Чем глубже вы будете погружаться в Java, тем
95 | чаще вы будете с ними сталкиваться. Как в рамках курса, так и после него, в коммерческой разработке. Поэтому очень
96 | важно освоить основную информацию уже сейчас.
97 |
98 | #### С теорией на сегодня все!
99 |
100 | 
101 |
102 | Переходим к практике:
103 |
104 | ## Задача 1:
105 |
106 | Реализуйте
107 | [задачу](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson14_polymorphism/task1)
108 |
109 | 1. используя абстрактный класс;
110 | 2. используя интерфейс.
111 |
112 | Какой вариант удобнее в реализации? Какой кажется вам более правильным? Возможно, в вашем решении нужны и абстрактные
113 | классы, и интерфейсы одновременно?
114 |
115 | ## Задача 2:
116 |
117 | Реализуйте
118 | [задачу](https://github.com/KFalcon2022/practical-tasks/blob/master/src/com/walking/lesson3_casts_conditional_constructions/Task2SwitchCase.java)
119 | с использованием интерфейсов. Каждая реализация должна возвращать свое сообщение.
120 |
121 | ## Задача 3:
122 |
123 | Реализуйте любую задачу из уроков о
124 | [наследовании](https://github.com/KFalcon2022/lessons/blob/master/lessons/java-core/013/Inheritance.%20Keywords%20extends%20and%20super.%20Access%20modifier%20protected.md)
125 | или [полиморфизме](https://github.com/KFalcon2022/lessons/blob/master/lessons/java-core/014/Polymorphism.%20Overriding%20method.%20Types%20of%20polymorphism.md)
126 | с использованием новых знаний. Выбирайте инструмент с умом.
127 |
128 | **Разбор практики для этого урока**:
129 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson16_abstract_class_interface)
130 |
131 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
132 | >
133 | > Канал: https://t.me/ViamSupervadetVadens
134 | >
135 | > Мой тг: https://t.me/ironicMotherfucker
136 | >
137 | > **Дорогу осилит идущий!**
138 |
--------------------------------------------------------------------------------
/lessons/java-core/003/Type casting. Conditional operators and little bit about Strings.md:
--------------------------------------------------------------------------------
1 | # Преобразование типов, условные конструкции и немного о строках
2 |
3 | ## Преобразование типов
4 |
5 | Как может стать понятно из названия, речь пойдет о переводе данных из одного типа в другой. На профессиональном сленге
6 | чаще используется **каст/кастинг** (от англ. _cast_).
7 |
8 | Зачем это нужно? Вариантов масса, но чаще это актуально для ссылочных типов(суть там немного другая, но принцип тот же).
9 | Для примитивов это может быть актуально, например, когда нам требуется разделить два целых числа, не теряя остаток:
10 |
11 | ```java
12 | int a = 10;
13 | int b = 3;
14 | System.out.println(a / b); //3
15 | ```
16 |
17 | Результат операций над целыми числами – целое число. Но достаточно маленькой доработки:
18 |
19 | ```java
20 | int a = 10;
21 | int b = 3;
22 | System.out.println((double) a / b); //3.3333333333333335
23 | ```
24 |
25 | И Java сразу вспоминает о правилах арифметики. Правда, со своим колоритом. 5 на конце – не опечатка. Это связанно с
26 | особенностями хранения данных в памяти, о чем было упомянуто в конце
27 | [статьи](https://metanit.com/java/tutorial/2.3.php).
28 |
29 | Однако вернемся к приведению типов. [Ссылка на материал](https://metanit.com/java/tutorial/2.2.php).
30 |
31 | К сожалению, ссылок на видео пока нет, ибо автор публиковавшихся ранее видео достаточно сжато рассказывал эти темы. Если
32 | знаете подходящие материалы от других авторов – делитесь в комментах или мне в личку, возможно, что-то в итоге окажется
33 | в статьях:)
34 |
35 | ### Итак, на что стоит обратить внимание:
36 |
37 | - Какие преобразования выполняются неявно и не требуют от нас дополнительных действий, а какие происходят только при
38 | явном указании программиста и почему;
39 | - Какие преобразования могут привести к потере точности (их не так много);
40 | - В каких случаях возможна потеря данных (потеря точности и потеря данных – разные вещи);
41 | - Как можно округлять числа в Java (с классом `Math` мы еще столкнемся, но не слишком плотно).
42 |
43 | ## Условные конструкции
44 |
45 | Эта тема многим дается тяжелее, чем предыдущие, поэтому крайне советую разобраться в ней досконально, иначе дальше будет
46 | тяжело.
47 |
48 | Итак, что же это за зверь. **Условная конструкция** – синтаксический элемент языка, который позволяет в зависимости от
49 | результата определенного условного выражения (условные выражения были буквально вчера) выполнить либо одни, либо другие
50 | действия.
51 |
52 | Подробнее ознакомимся в [статье](https://metanit.com/java/tutorial/2.5.php).
53 |
54 | Также видео. К сожалению, несколько засрано рекламой от автора, но, на первый взгляд, крайне подробно разжевывает данную
55 | тему: [](https://www.youtube.com/watch?v=SdGp-5pcPeA)
56 |
57 | ### Итак, на что стоит обратить внимание:
58 |
59 | * Что же такое конструкция `if-else`? Бывает ли `if` без `else`? `Else` без `if`?
60 | * Какие условия могут быть в `if`? Могут ли быть несколько условий?
61 | * Условие в `if` всегда должно принимать значение типа `boolean` – `true` или `false`;
62 | * Разница между `if`, идущими друг за другом(`if(){} if(){}`) и `if(){} else if(){};`
63 | * Как использовать конструкцию `switch-case`, для чего она нужна;
64 | * Для чего нужен `default` в `switch-case`;
65 | * Зачем нужен `break` и что будет, если его не использовать;
66 | * Можно ли использовать `if` внутри другого `if`? `If` в `switch-case`, `switch-case` внутри `if`?
67 | * Что такое тернарная операция (она упоминалась в уроке про приоритеты операций);
68 | * Ограничения использования тернарных операций.
69 |
70 | Пару слов о тернарных операциях, поскольку эта информация не освещается по ссылкам выше:
71 |
72 | 1. Использовать тернарную операцию мы можем только если из нее возвращается какое-либо значение. Мы его обязательно
73 | записываем в переменную (или возвращаем из метода, но об этом не сегодня);
74 | 2. Тернарные операции можно вкладывать друг в друга. Но не нужно, поэтому примера не будет. Это является плохой
75 | практикой, поскольку сильно снижает читаемость кода.
76 |
77 | > **!NB**: Статья на metanit содержит вопросы для самопроверки и практические упражнения.
78 |
79 | ## Совсем немного о строках. И еще меньше об операторах
80 |
81 | В предыдущих уроках вы могли встретить формы записи `"строка" + "строка"` или `"строка" + 1` (или любое другое
82 | число/переменная численного типа) и прочие варианты. Немного разберемся в том, что это за странное сложение и
83 | как оно работает.
84 |
85 | Сложение (склеивание) строк называется **конкатенацией**. По сути, мы берем две строки (или строку и символ, строку и
86 | число) и объединяем их в одну строку. Можно еще склеить строку и объект, но это не сегодня и механизм там несколько
87 | другой. В плане использования нет ничего сложного.
88 |
89 | Но нюансы возникают, когда мы пытаемся склеить, например, символ и число или даже два символа между собой. На выходе
90 | получается другое число. Почему так?
91 |
92 | Дело в том, что оператор `+` используется в Java для операции сложения. Вроде бы все логично. Но именно для действий со
93 | строками этот оператор был перегружен и используется для конкатенации.
94 |
95 | Перегрузка оператора – наделение оператора другим значением, кроме заданного изначально. К слову, в отличие от ряда
96 | других языков (С++ и др.), программист в Java не имеет возможности самостоятельно перегружать операторы. `+` для строк –
97 | единственное исключение, когда сами разработчики языка заложили в оператор двойственность поведения.
98 |
99 | И, как можно догадаться, перегружен оператор был ТОЛЬКО для строк. К символам поведение конкатенации не относится.
100 | Почему при сложении символов вообще что-то работает?
101 |
102 | Все дело в том, что каждому символу соответствует свой числовой код (можете самостоятельно почитать про Unicode,
103 | UTF-кодировки и их альтернативы). И эти коды возможно могут быть нужны разработчику. Например, вы решите написать программу
104 | по переводу прописных букв в строчные (`А` – `а` и т.д.). Здесь коды символов могут вам помочь.
105 |
106 | Собственно, отсюда растут ноги у неочевидной, на первый взгляд, логики поведения оператора `+`.
107 |
108 | #### С теорией на сегодня все!
109 |
110 | 
111 |
112 | Переходим к практике:
113 |
114 | ## Задача 1:
115 |
116 | Ввести с клавиатуры два целых числа. Если _Число1_ четное, вывести произведение двух чисел (пр.1), если нет - частное
117 | (пр.2). Также если числа равны - вывести надпись `Числа равны!`
118 |
119 | пр1.: `Число1 * Число2 = Произведение`, где `число1` - значение 1-го числа, `число2` - значение 2-го числа,
120 | `Произведение` - результат умножения.
121 |
122 | пр2.: `Число1 / Число2 = Частное`, где `число1` - значение 1-го числа, `число2` - значение 2-го числа, `Частное` -
123 | результат деления. Помните, что в Java результатом деления двух целых чисел будет целое число.
124 |
125 | ## Задача 2:
126 |
127 | Написать программу, которая принимает строку с клавиатуры:
128 | - Если введенная строка равна `Hi` - вывести в консоль `Hello`;
129 | - Если `Bye` - `Good bye`;
130 | - Если `How are you` - `How are your doing`;
131 | - Если любая другая строка - вывести `Unknown message`.
132 |
133 | Реализуйте решение через:
134 |
135 | 1. if-else
136 | 2. switch-case
137 |
138 | > Примечание: для сравнения строк некорректно использовать оператор `==`, почему - разберем позже. Можно
139 | > воспользоваться методом `equals()`.
140 | >
141 | > Например: `"Hi".equals(s);` или `s.equals("Hi");`
142 |
143 | ## Задача 3:
144 |
145 | Заведите три переменные типа `String`. С клавиатуры введите в них вашу фамилию, имя и отчество соответственно.
146 | Выведите в консоль ваше ФИО в одну строку.
147 |
148 | Реализуйте, используя:
149 |
150 | 1. `System.out.println()`
151 | 2. `System.out.printf()`
152 |
153 | ## Задача 4:
154 |
155 | Введите с клавиатуры два целых числа. Если первое – четное ИЛИ второе – кратно трем, выведите в консоль результат
156 | сравнения этих чисел в любом формате. Например, `Число1 больше Числа2`. Или `true` (если числа равны) и `false` -
157 | если нет.
158 |
159 | Если первое число кратно и двум, и трем – также выведите на экран число один, возведенное в степень `N`, где `N` –
160 | второе число. Для возведения в степень можно использовать `Math.pow()`. В случае, если результат выражения выходит за
161 | пределы типа `int` (допустимые значения - [-2147483648; 2147483647]) – вывести сообщение
162 | `Результат выражения слишком большой!`.
163 |
164 | Также минимальное и максимальное значение `int` содержится в константах `Integer.MIN_VALUE` и `Integer.MAX_VALUE`
165 | соответственно.
166 |
167 | **Разбор практики для этого урока**:
168 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson3_casts_conditional_constructions)
169 |
170 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
171 | >
172 | > Канал: https://t.me/ViamSupervadetVadens
173 | >
174 | > Мой тг: https://t.me/ironicMotherfucker
175 | >
176 | > **Дорогу осилит идущий!**
177 |
--------------------------------------------------------------------------------
/lessons/java-core/019/Object methods.md:
--------------------------------------------------------------------------------
1 | # Методы класса Object
2 |
3 | Сегодня мы познакомимся с содержимым класса Object, а именно, с методами, которые он содержит. Не все из них
4 | действительно востребованы, часть методов мы пока не сможем применить, потому что не знакомы с концепциями, для которых
5 | они нужны (например, несколько методов связаны с многопоточностью). Соответственно, периодически мы будем возвращаться к
6 | этой теме в дальнейшем.
7 |
8 | Для начала, ознакомимся со [статьей](https://metanit.com/java/tutorial/3.9.php)
9 |
10 | Кроме представленных в ней методов есть также:
11 |
12 | 1. Три перегруженных метода `wait()`. Относятся к разработке **многопоточных** приложений. В явном виде обычно не
13 | используются. Указывают потоку на необходимость ожидать (в течении какого-то времени или до
14 | вызова `notify()`/`notifyAll()`);
15 | 2. Методы `notify()` и `notifyAll()`. Относятся к разработке многопоточных приложений. В явном виде обычно не
16 | используются. Вкратце, необходимы для оповещения произвольного потока (или всех потоков), ожидающих доступ к объекту,
17 | занятому другим потоком, о том, что объект доступен;
18 | 3. Метод `finalize()`. Помечен аннотацией `@Deprecated` — устарел. Не рекомендуется к использованию. Задумывался для
19 | очистки ресурсов и, в принципе, описания действий, которые необходимо выполнить перед удалением объекта из памяти. В
20 | явном виде его вызов недопустим. Очистка памяти в Java полностью автоматизирована;
21 | 4. Метод `clone()`. Необходим для **клонирования** (создания нового объекта с теми же значениями полей) объектов. В
22 | некотором смысле заменяет **конструктор копирования** (если кто-то с ним знаком в других языках). Практически не
23 | используется на практике, но в отдельном уроке мы рассмотрим тему клонирования и его виды. Для
24 | переопределения `clone()` необходимо в классе реализовать маркерный интерфейс `Cloneable`.
25 |
26 | Также стоит сказать несколько слов о методе `toString()`, описанном в статье выше. Несмотря на кажущуюся полезность, он
27 | редко используется в реальных задачах. При необходимости конвертировать объект в строку (обычно, для создания
28 | JSON-объектов, с ними мы еще познакомимся) используются сторонние библиотеки. Таким образом, этот метод оказался на
29 | обочине жизни, как и многие другие. Но в рамках практических задач мы можем его использовать по мере необходимости.
30 |
31 | Учтите, что метод `toString()` вызывается внутри методов `print()`, `printf()`, `println()`, если в них передать объект.
32 | Также при конкатенации строк через `+` для не строковых ссылочных типов также происходит неявный вызов `toString()`.
33 |
34 | Я рекомендую ознакомиться с документацией по `Object` самостоятельно, для закрепления информации. Для разных версий JDK
35 | описание может незначительно
36 | отличаться. [Ссылка для Java 17](https://docs.oracle.com/en/java/javase/17/docs/api/index.html)
37 |
38 | Также документация доступна в виде **Java-doc** в IDEA, достаточно открыть класс `Object`.
39 |
40 | > Прежде чем мы продолжим, советую обратить внимание на ключевое слово `native`, оно используется по отношению к
41 | > некоторым методам в `Object` (и не только). Означает, что метод был реализован на языке, отличном от Java. Мы можем
42 | > такой метод использовать, но просмотр тела метода нам недоступен.
43 |
44 | ## Правила переопределения equals()
45 |
46 | Метод `equals()` — один из наиболее используемых методов `Object`. Но в базовой реализации он сравнивает ссылки на
47 | объекты. Т.е. `true` он вернет только если сравнивать две переменные, которые ссылаются на один и тот же объект.
48 |
49 | Чтобы использовать `equals()` для настоящего сравнения объектов, его необходимо переопределить.
50 |
51 | Правила переопределения основаны на контракте `equals()` — договоренности, какое поведение ожидается от этого метода.
52 |
53 | Контракт определяет следующие характеристики:
54 |
55 | 1. **Рефлексивность**. Иными словами, `x.equals(x) == true;`
56 | 2. **Симметричность**: если `x.equals(y)`, то и `y.equals(x)`;
57 | 3. **Переносимость**: если `x.equals(y)` и `y.equals(z)`, то и `x.equals(z)`;
58 | 4. **Консистентность**: повторное выполнение `x.equals(y)` без изменения состояния (полей) объектов `x` и `y` должно
59 | возвращать один и тот же результат;
60 | 5. **Сравнение с NULL**: `x.equals(null) == false`.
61 |
62 | Таким образом, классический переопределенный `equals` выглядит примерно так:
63 |
64 | ```java
65 | public boolean equals(Object o) {
66 | if (this == o) { //Гарантируем рефлексивность
67 | return true;
68 | }
69 | if (o == null) {
70 | return false;
71 | }
72 | if (!getClass().equals(o.getClass())) { // Возможны вариации.
73 | // Использование instanceof или сравнение типа параметра с явно вызванным
74 | // литералом класса: o.getClass().equals(SthClass.class)
75 | return false;
76 | }
77 | SthClass sthClass = (SthClass) o; // К этой строке мы уже уверены, что тип верный и можно кастить.
78 | // При использовании instanceof это можно описать немного лакончинее
79 |
80 | // Ниже будет сравнение по полям. Если значение по всем проверяемым полям совпадают возвращаем из метода true,
81 | // если хоть в одном поле значения отличаются - false
82 | }
83 | ```
84 |
85 | При проверке типа в `equals()` обычно используют проверку типа через `getClass()`. Но если в рамках вашей задачи
86 | допустимо сравнение с объектами наследников — допустимо использовать `instanceof`. Это не слишком частый, но возможный
87 | сценарий.
88 |
89 | При выборе полей для сравнения, стоит также руководствоваться здравым смыслом. Конечно, можно реализовать сравнение по
90 | всем полям. Но если в рамках задачи (или логики сущности в целом) некоторые поля не являются ключевыми — вполне логично
91 | их опустить в `equals()`.
92 |
93 | ## Правила переопределения hashCode()
94 |
95 | **Хэшкод** возвращает **хэш** объекта. Иными словами, некоторое число, рассчитанное на основании значения полей.
96 |
97 | Метод возвращает `int`, соответственно, количество уникальных значений хэшкода ограничено и он может совпадать у
98 | различных по значениям полей объектов. Совпадение хэшей (хэшкодов) при разных входных данных называется **коллизией**.
99 |
100 | Поведение по умолчанию у `hashCode()` зависит от настроек JVM. В любом случае, если мы хотим его использовать
101 | (например, `hashCode()` используется во многих коллекциях), мы обязаны его переопределить. Переопределенный хэшкод
102 | выглядит примерно так:
103 |
104 | ```java
105 | public int hashCode() {
106 | int result = field1 != null ? field1.hashCode() : 0;
107 | result = 31 * result + (field2 != null ? field2.hashCode() : 0);
108 | // ...
109 | result result;
110 | }
111 | ```
112 |
113 | Алгоритмы расчета хэшкода могут отличаться, это не критично на данном этапе. В рамках этого алгоритма мы можем увидеть
114 | умножение на `31`. Оно необходимо для более равномерного распределения значений по множеству `int`.
115 |
116 | При выборе полей для расчета `hashCode()` необходимо брать те же поля, что и для `equals()`. Подробнее ниже.
117 |
118 | ## Контракт equals() и hashCode()
119 |
120 | Эти два метода зачастую нужны вместе (например, во многих коллекциях), поэтому существует определенный контракт их
121 | взаимодействия:
122 |
123 | 1. Переопределяя один метод, необходимо переопределить второй;
124 | 2. Равенство объектов по `equals()` гарантирует равенство их хэшкодов;
125 | 3. Равенство хэшкодов не гарантирует равенства объектов по `equals()`.
126 |
127 | Последний пункт не очень удачен с точки зрения формулировки контракта, но распространен в сообществе. Его также можно
128 | заменить на: неравенство хэшкодов гарантирует неравенство объектов по `equals()`.
129 |
130 | Именно для соблюдения контракта `equals()` и `hashCode()` возникает необходимость использовать при их переопределении
131 | одни и те же поля.
132 |
133 | Вопросы о методах класса `Object` и рассмотренных выше контрактах часто задают на собеседованиях для
134 | junior-специалистов. А иногда и не только им.
135 |
136 | #### С теорией на сегодня все!
137 |
138 | 
139 |
140 | Приступаем к практике:
141 |
142 | ## Задача:
143 |
144 | Реализуйте класс _Машина_. Поля допустимо выбрать на свое усмотрение, но необходимо, чтобы по ним можно было
145 | однозначно идентифицировать каждую машину. Скажем, в рамках базы ГАИ.
146 |
147 | Создайте массив машин. Реализуйте максимально эффективную проверку на вхождение машины в ваш массив. Данные для проверки
148 | необходимо запрашивать с клавиатуры.
149 |
150 | Если машина найдена — выведите ее строковое представление в консоль.
151 |
152 | Опциональное усложнение: номер машины может быть не уникальным.
153 |
154 | **Разбор практики для этого урока**:
155 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson19_object_methods)
156 |
157 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
158 | >
159 | > Канал: https://t.me/ViamSupervadetVadens
160 | >
161 | > Мой тг: https://t.me/ironicMotherfucker
162 | >
163 | > **Дорогу осилит идущий!**
164 |
--------------------------------------------------------------------------------
/lessons/jdbc/132/JDBC. Tranastions.md:
--------------------------------------------------------------------------------
1 | # JDBC и транзакции
2 |
3 | До этого момента мы взаимодействовали с БД преимущественно через одиночные запросы, никак не управляя
4 | транзакционностью их выполнения. В этой статье разберем, какое API для работы с транзакциями предоставляет JDBC.
5 |
6 | ## Автокоммит
7 |
8 | Хорошая новость в отношении сегодняшней темы - при работе через JDBC не надо в явном виде писать запросы с открытием
9 | транзакции и ее фиксацией - для этого определен специальный набор методов на уровне Connection'а.
10 |
11 | Плохая же заключается в том, что особенности реализации порождают некоторые новые конструкты - в более высокоуровневых
12 | инструментах такие конструкты превращаются в отдельные слои абстракции со своими особенностями и ограничениями. В нашем
13 | случае все достаточно просто - у нас появляется понятие автокоммита.
14 |
15 | Автокоммит - свойство подключения, которое определяет, будет ли фиксироваться результат каждого отдельного запроса
16 | автоматически. Это эквивалентно выполнению такого запроса вне транзакции: даже если следующие запросы, сделанные
17 | через тот же объект `Connection`* будут содержать ошибку - каждый из предыдущих уже будет зафиксирован в БД и ни при
18 | каких условиях не будет откачен.
19 |
20 | > *Безусловно, API для запросов к БД предоставляют объекты `Statement` (или его наследники). Но физическое
21 | > подключение к БД и, следовательно, управление транзакциями, является ответственностью `Connection`, который и
22 | > породил используемые для запросов Statement'ы.
23 |
24 | Автокоммит по умолчанию включен. Это дает картину, привычную по работе с СУБД напрямую: каждый запрос выполняется
25 | самостоятельно, вне транзакции. Могут быть особенности при работе с батчами, но они не всегда связаны с
26 | транзакционностью выполнения, и не имеют прямого отношения к сегодняшней теме.
27 |
28 | Соответственно, чтобы выполнять запросы транзакционно требуется лишь отключить автокоммит и после зафиксировать
29 | транзакцию. Никаких явных запросов `BEGIN`.
30 |
31 | ## API
32 |
33 | Практическая сторона вопроса достаточно тривиальна: мы имеем несколько методов, позволяющих включить (или выключить)
34 | режим автокоммита, а также методы для коммита и отмены транзакции. Также существует метод, позволяющий установить
35 | уровень изоляции, если нас не устраивает значение по умолчанию.
36 |
37 | Но обо всем по порядку.
38 |
39 | ### Автокоммит
40 |
41 | - `getAutoCommit()`. Данный метод возвращает `true`, если автокоммит включен, и `false` - если автокоммит выключен.
42 | Последнее состояние позволяет выполнять запросы транзакционно;
43 | - `setAutoCommit(boolean autoCommit)`. Устанавливает состояние автокоммита. Стандартный сценарий использования -
44 | вызов с `false` в параметре при необходимости выполнить какие-либо запросы внутри транзакции.
45 |
46 | ### Уровни изоляции
47 |
48 | Для работы с уровнем изоляции предлагаются следующие два метода:
49 |
50 | - `getTransactionIsolation()`. Возвращает `int`, обозначающий код уровня изоляции, установленный на данный момент.
51 | Примеры можно найти ниже;
52 | - `setTransactionIsolation(int level)`. Устанавливает уровень изоляции в соответствие с указанным кодом. Обычно
53 | вызывается сразу после выключения автокоммита, если необходимо.
54 |
55 | Коды могут быть следующими (`Connection` содержит константы для этих значений):
56 |
57 | - `0`. Соответствует отсутствию транзакции. Фактически, это означает, что данная СУБД не поддерживает транзакции вовсе;
58 | - `1`. Уровень `READ UNCOMMITTED`;
59 | - `2`. Уровень `READ COMMITTED`. Является уровнем изоляции по умолчанию в большинстве СУБД;
60 | - `4`. Уровень `REPEATABLE READ`;
61 | - `8`. Уровень `SERIALIZABLE`.
62 |
63 | Использование иных значений в `setTransactionIsolation()` приведет к исключению.
64 |
65 | Фактический способ получения данного кода через вызов `getTransactionIsolation()` может отличаться в зависимости от
66 | драйвера. В случае с PostgreSQL - будет запрошен напрямую из БД.
67 |
68 | Использование `setTransactionIsolation()` посреди активной транзакции может привести к различным последствиям в
69 | зависимости от используемого драйвера. PostgreSQL - просто выбросит исключение.
70 |
71 | На практике использование этого метода разумно при непосредственной установке уровня изоляции перед отправкой
72 | транзакционных запросов (фактически - сразу после выключения автокоммита) и после фиксации транзакции - для
73 | установки уровня по умолчанию, если этот же `Connection` должен использоваться в дальнейшем.
74 |
75 | ### Фиксация транзакций
76 |
77 | После того как мы выключили автокоммит и выполнили необходимые запросы необходимо зафиксировать транзакцию:
78 |
79 | - `commit()`. Попытается зафиксировать успешное выполнение транзакции. Если при этом будет включен автокоммит -
80 | выбросит исключение;
81 | - `rollback()`. Откатит текущую транзакцию. Так же выбросит исключение, если включен автокоммит. Обычно используется
82 | в catch-блоке - при этом транзакционные запросы и `commit()` вызываются в try-блоке перед ним.
83 |
84 | С учетом API, описанного выше, пример работы с транзакцией через JDBC можно описать так:
85 |
86 | ```java
87 | try (Connection connection = getConnection();
88 | Statement statement = connection.createStatement()) {
89 |
90 | connection.setAutoCommit(false);
91 |
92 | // Опционально. В данном случае - установка уровня изоляции REPEATABLE READ
93 | connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
94 |
95 | try {
96 | statement.executeUpdate("insert into passenger (first_name, last_name, birth_date) values ('Name2', 'Surname2', '1997-12-20')");
97 | statement.executeUpdate("update passenger set first_name = 'IVAN' where id = 1");
98 |
99 | connection.commit();
100 | } catch (Exception e) {
101 | connection.rollback();
102 | log.error("Транзакция была откачена");
103 | }
104 | } catch(SQLException e) {
105 | log.error(e);
106 | }
107 | ```
108 |
109 | Безусловно, мы также можем использовать `PreparedStatement` или иные виды Statement'ов. Если они были получены через
110 | тот же объект `Connection` - их запросы будут выполняться в той же транзакции.
111 |
112 | При этом, обратите внимание, откат транзакции может быть произведен не только из-за ошибок при выполнении запроса -
113 | технически, в try-блоке может быть еще какая-то логика - даже не факт, что связанная с БД - и исключение в ней также
114 | приведет к откату транзакции. Это дает возможность более гибко управлять транзакциями, вплетая их в выполнение
115 | функциональности приложения. Не всегда такой подход будет правильным с точки зрения проектирования, но в данном
116 | случае важен сам факт.
117 |
118 | ### Savepoint
119 |
120 | Кроме базового инструментария для работы с транзакциями также существует поддержка savepoint'ов, с которыми мы
121 | знакомились в разделе SQL. В силу непопулярности данного инструмента я не вижу смысла углубляться в его JDBC API,
122 | лишь отмечу методы, которые могут стать точками входа в эту тему:
123 |
124 | - `setSavepoint()`;
125 | - `releaseSavepoint()`;
126 | - `rollback(Savepoint savepoint)`.
127 |
128 | В целом, они дают ту же функциональность, что и перекликающиеся с ними команды SQL, являясь, по сути, обычными
129 | прокси над соответствующими запросами.
130 |
131 | ## Заключение
132 |
133 | Это завершающая статья раздела JDBC. Но это лишь начало в объемной теме взаимодействия Java-приложения и реляционных
134 | СУБД.
135 |
136 | Как неоднократно упоминалось ранее, шанс встретить голый JDBC в реальном проекте - достаточно низкий. Однако именно
137 | он является основной для более продвинутых инструментов, с некоторыми из которых мы будем знакомиться в дальнейших
138 | разделах.
139 |
140 | И если данный раздел носил скорее ознакомительный характер, то следующие будут более практико-ориентированными,
141 | поскольку будут знакомить с инструментами, которые большинству Java-разработчиков нужны в работе ежедневно. Или, по
142 | крайней мере, владение этими инструментами является требованием по умолчанию.
143 |
144 | Так, уже в следующих уроках мы познакомимся с инструментами миграций и Connection Pool'ами, через несколько разделов -
145 | с Hibernate и в рамках последнего большого раздела курса - Spring - со спецификой работы с РСУБД в Spring'овой же
146 | экосистеме. Которая включает, в том или ином виде, все остальные инструменты, указанные в этом абзаце.
147 |
148 | #### С теорией на сегодня все!
149 |
150 | 
151 |
152 | Переходим к практике:
153 |
154 | ## Задача
155 |
156 | На базе [репозитория](https://github.com/KFalcon2022/jdbc-practical-tasks) реализуйте следующую функциональность:
157 |
158 | - Реализуйте CRUD для работы с билетами. Функциональность должна быть аналогична таковой у пассажиров, включая
159 | пакетные операции;
160 | - Добавьте метод для приобретения билета с одновременным созданием пассажира, если последнего не существует в БД.
161 | Метод должен быть транзакционным;
162 | - Покройте новую функциональность юнит-тестами.
163 |
164 | Ветка для PR: `for-pr`.
165 |
166 | **Разбор практики для этого урока**:
167 | [ссылка](https://github.com/KFalcon2022/jdbc-practical-tasks/commit/b0ec97eafeecc79e9e4fc3f4b1449ce2a17c2bd5)
168 |
169 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
170 | >
171 | > Канал: https://t.me/ViamSupervadetVadens
172 | >
173 | > Мой тг: https://t.me/ironicMotherfucker
174 | >
175 | > **Дорогу осилит идущий!**
176 |
--------------------------------------------------------------------------------
/lessons/java-core/012/Encapsulation. Packages. Access modifiers. Getters and setters.md:
--------------------------------------------------------------------------------
1 | # Инкапсуляция. Пакеты. Модификаторы доступа. Getter'ы и Setter'ы
2 |
3 | ## Понятие инкапсуляции
4 |
5 | Сегодня мы разберемся с одним из принципов ООП — **инкапсуляцией**, а также средствами, которые используются в Java для
6 | ее достижения. Как синтаксическими, так и нет.
7 |
8 | С точки зрения базового определения, инкапсуляция — это объединение в одной структуре (в одном компоненте) данных и
9 | логики. В терминах Java — объединение полей и методов. Таким образом, определение инкапсуляции в каком-то смысле
10 | порождает уже знакомое нам понятие класса. Такое является достаточно вольной трактовкой, в силу того, что нам пока
11 | не знакомы некоторые термины, которые играют важную роль в более классической формулировке.
12 |
13 | С точки зрения применения, инкапсуляция часто заключается в сокрытии данных или реализации логики. И именно на это будут
14 | направлены средства языка, которые мы изучим сегодня.
15 |
16 | Стоит сразу отметить, что сокрытие, как данных, так и реализации, относится не к невозможности увидеть код или узнать
17 | состояние объекта в процессе выполнения, а к невозможности получить какие-то поля/методы за пределами
18 | класса/пакета/иерархии наследования.
19 |
20 | Также можно говорить об инкапсуляции определенной логики в более глубоком смысле, в контексте жесткого ограничения
21 | ответственности конкретных классов или модулей (что бы это слово не значило), но в рамках теоретической части курса мы
22 | будем касаться этого лишь поверхностно. Больше внимание этому аспекту будет уделяться в практических заданиях.
23 |
24 | ## Пакеты
25 |
26 | **Пакеты** в Java — механизм, который, на первый взгляд, можно свести к обычным файловым директориям (папкам). Полагаю,
27 | все понимают назначение папок на диске.
28 |
29 | Однако в совокупности с **модификаторами доступа** (которым посвящен следующий подраздел), пакеты также участвуют в
30 | ограничении доступа к данным (классам, конструкторам, полям или методам). Но об этом ниже.
31 |
32 | С базовым синтаксисом предлагаю ознакомиться в [статье](https://metanit.com/java/tutorial/3.2.php).
33 |
34 | Кроме того, рекомендую обратить внимание на следующие вещи:
35 |
36 | * Пакеты принято именовать строчными буквами, в единственном числе. Рекомендуется использовать одно слово для названия
37 | пакета. Если пакет невозможно определить одним словом, способ разделения слов (или его отсутствие), определяются в
38 | рамках команды;
39 | * Вложенные пакеты — не часть внешних пакетов. Т.е. если у нас есть классы/поля/методы, видимость которых ограничена
40 | (см. модификаторы доступа) в рамках пакета `a`, они не будут доступны в рамках пакета `a.b`. И наоборот. Пакеты в
41 | Java — это не древовидная структура, каждый пакет(`a`, `a.b`) является просто идентификатором, даже если физически он
42 | находится внутри другого пакета;
43 | * Пакеты в Java принято разбивать на основе назначения классов, а не **доменной логики**. Условно, в программе, которая
44 | содержит классы создания треугольника и квадрата, а также свои классы-принтеры для каждой фигуры, пакеты стоит
45 | разбивать как: `figure`, `printer`. И ни в коем случае не `triangle`, `square`;
46 | * Существует общепринятый подход к пакетам верхнего уровня. Он определяет первые три уровня пакетов. Т.е. даже в примере
47 | выше пакеты `figure` и `printer` должны оказаться на четвертом уровне вложенности. Разберемся подробнее в отдельном
48 | абзаце.
49 |
50 | Первые два уровня пакетов — доменное имя компании в обратном порядке. В качестве примера возьмем `google.com`. В
51 | продуктах от Google на Java самым верхним пакетом будет `com`, в нем будет лежать пакет `google`. Пакет третьего
52 | уровня — обозначение (название) проекта. Далее идут пакеты функционального уровня, которые зависят от потребностей
53 | продукта. Т.е. в общем виде полное название пакетов в гугле можно определить как:
54 |
55 | ```
56 | com.google...
57 | ```
58 |
59 | Визуализировать структуру можно так:
60 |
61 | ```
62 | - com
63 | -- google
64 | --- {projectName} — в этом пакете обычно находится класс с методом main()
65 | ---- {sthPackage1}
66 | ---- {sthPackage2}
67 | ----- {sthSubPackageInPackage2}
68 | ...
69 | ```
70 |
71 | Пакеты — важный инструмент в Java. Как с точки зрения удобства разделения классов по назначению, так и с точки
72 | зрения инкапсуляции, поскольку позволяет ограничить доступ к классам (или их полям и методам) пределами пакета, где они
73 | определены. Но для этого нам нужны **модификаторы доступа**.
74 |
75 | ## Модификаторы доступа
76 |
77 | Этот механизм предназначен как раз для того, чтобы явно обозначить, где должен быть доступен класс, его поля и методы.
78 |
79 | Предлагаю ознакомиться со [статьей](https://metanit.com/java/tutorial/3.3.php).
80 |
81 | Также в комментариях к статье была достаточно наглядная картинка:
82 | 
83 |
84 | К модификатору `protected` мы еще вернемся в следующем уроке (наследование). На данном этапе нам не хватает знаний
85 | синтаксиса, чтобы закрепить его использование.
86 |
87 | Стоит отметить, что модификатор доступа "по умолчанию" (на картинке выше — **no modifier**) также называют
88 | **package-private**, что в большей степени описывает его область видимости.
89 |
90 | В контексте применения модификаторов доступа внутри класса можно вывести несколько базовых пунктов:
91 |
92 | * Не константные поля классов принято определять как `private`;
93 | * Методы, реализующие основную ответственность класса - `public`;
94 | * Методы, которые не предполагается использовать за пределами класса (созданные в рамках декомпозиции больших публичных
95 | методов или какие-то переиспользуемые внутри класса методы, не имеющие смысла вне его) - `private`;
96 | * Конструкторы - обычно `public`. Бывает иначе, но до этого мы еще дойдем.
97 |
98 | ## Getter'ы и Setter'ы
99 |
100 | **Геттеры** и **сеттеры** — классические во многих ООП-языках методы для получения и изменения поля. В ряде языков для
101 | них есть **синтаксический сахар**, в Java — нет. Нужны они для разграничения работы с конкретным полем.
102 |
103 | В общем случае, метод-геттер возвращает значение поля класса, к которому относится. Метод-сеттер — принимает в качестве
104 | параметра значение, которое нужно установить полю.
105 |
106 | Каждому полю соответствует свой геттер и свой сеттер.
107 |
108 | Также возможна ситуация, когда геттер (метод, возвращающий значение поля) есть, а сеттер — нет. Например, потому что не
109 | предполагается прямое изменение этого поля извне.
110 |
111 | В качестве общего примера для геттеров и сеттеров рассмотрим условный класс:
112 |
113 | ```java
114 | public class SthClass {
115 | private String sthField;
116 |
117 | public String getSthField() {
118 | return sthField;
119 | }
120 |
121 | public String setSthField(String sthField) {
122 | this.sthField = sthField;
123 | }
124 | }
125 | ```
126 |
127 | Здесь `getSthField()` — геттер поля `sthField`, `setSthField()` — сеттер этого поля.
128 |
129 | Почти всегда логика геттера заключается только в том, чтобы вернуть поле, а сеттера — в присвоении нового значения.
130 | Крайне редко, но бывают ситуации, когда тела этих методов содержат еще какую-то функциональность. Однако на данном этапе
131 | предлагаю не заострять на этом внимание, ибо кейсы использования дополнительной логики действительно узкие.
132 |
133 | > **!NB**: комбинация клавиш `alt`+`insert` предложит вам сформировать стандартные геттеры и/или сеттеры для полей,
134 | > конструкторы по выбранным вами параметрам и еще некоторые вещи, с которыми мы еще не знакомы.
135 |
136 | Возвращаясь к практике применения геттеров и сеттеров, в общем случае, поля должны быть приватными (`private`),
137 | а геттеры и сеттеры — публичными (`public`). На практике бывают разные ситуации, но они зависят от конкретных задач и
138 | особенностей их реализации.
139 |
140 | Геттеры и сеттеры непривычны сначала и их использование кажется неудобным. Но именно они могут спасти вас от проблем со
141 | случайной перезаписью значения, а в дальнейшем — дают гибкий инструмент настройки доступов к полям.
142 |
143 | ## В качестве вывода
144 |
145 | Инкапсуляция, как и любой другой принцип ООП, достаточно проста в базовом применении. Синтаксис и общепринятые практики
146 | ее достижения не являются чем-то сложным. С опытом и набитыми шишками многие вещи покажутся глубже, чем сейчас. Однако
147 | уже сейчас стоит убедиться, что изученный принцип понятен на базовом уровне, а изученный синтаксис не вызывает полного
148 | непонимания.
149 |
150 | #### С теорией на сегодня все!
151 |
152 | 
153 |
154 | Переходим к практике:
155 |
156 | С этого урока предлагаю принять, что все мы разрабатываем продукты для компании walking.com, соответственно,
157 | пакеты 1го и 2го уровня: `com.walking`.
158 |
159 | ## Задача:
160 |
161 | Разработать программу в рамках компании walking/com, позволяющую следить за счетчиками на газ, холодную воду, горячую
162 | воду и электричество. Обозначение программы в рамках компании — `counterAggregation`.
163 |
164 | Используя за основу
165 | [задачу](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson8_classes_objects)
166 | из темы про классы и объекты, реализовать класс счетчика, который хранит название счетчика и его значение, его единицы
167 | измерения, а также обеспечивает доступ к значениям. Название счетчика и его единицы измерения должны быть неизменны.
168 |
169 | Также реализовать сервис `CounterService`, зона ответственности которого — хранение массива доступных счетчиков,
170 | получение всех доступных счетчиков, получение доступа к счетчику по названию, увеличение значения счетчика на единицу
171 | или заданное значение, а также сброс счетчика до нулевого значения.
172 |
173 | Ответственность класса, содержащего `main()` — создание счетчиков. Сам класс также предлагаю назвать `Main`.
174 |
175 | Также реализовать в классе `Main` приватный метод, который позволяет вывести значения счетчиков в виде:
176 |
177 | ```
178 | <Название счетчика>: <Значение счетчика>
179 | ```
180 |
181 | Например:
182 |
183 | ```
184 | Газ: 2333
185 | Горячая вода: 0
186 | Холодная вода: 23
187 | ...
188 | ```
189 |
190 | **Разбор практики для этого урока**:
191 | [ссылка](https://github.com/KFalcon2022/CounterAggregation)
192 |
193 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
194 | >
195 | > Канал: https://t.me/ViamSupervadetVadens
196 | >
197 | > Мой тг: https://t.me/ironicMotherfucker
198 | >
199 | > **Дорогу осилит идущий!**
200 |
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/139/HTTP clients.md:
--------------------------------------------------------------------------------
1 | # HTTP-клиенты. Практика отправки запросов
2 |
3 | Мы уже изучили достаточно большой объем теоретической информации об HTTP и пришло время закрепить ее на практике. Для
4 | этого нам необходимо познакомиться с понятием **HTTP-клиента** и изучить работу с одним или нескольким из них.
5 |
6 | ## HTTP-клиенты
7 |
8 | HTTP-клиент - программа или программный компонент, который предоставляет возможность отправлять
9 | HTTP-запросы. В зависимости от контекста значение может немного разниться, но общая суть остается той же.
10 | HTTP-клиент, в узком понимании, является тем самым клиентом в клиент-серверном приложении. В случае, если это
11 | приложение общается по HTTP (а не другому протоколу), клиентом выступает именно HTTP-клиент.
12 |
13 | В целом, как минимум с одним HTTP-клиентом вы умеете работать - это обычный браузер. Но в данном случае отправка
14 | запросов не является его основной функцией - ведь большая часть его работы заключается в интерпретации ответов,
15 | которые получены в качестве ответа на запрос. Так, браузер умеет работать с HTML и JavaScript (который, в свою
16 | очередь, имеет свои средства для выполнения HTTP-запросов). Кроме того, браузеры обычно умеют работать с несколькими
17 | протоколами. И, наконец, браузер плохо подходит для ситуаций, когда нам необходимо именно отправлять запросы в
18 | ручном режиме, т.е. плохо подходит для тестирования и отладки запросов. Для этого есть более специализированные
19 | инструменты.
20 |
21 | За пределами браузера под HTTP-клиентом обычно понимают одно из двух:
22 |
23 | 1. Специализированная программа, предназначенная для отправки HTTP-запросов. В отличие от стандартных средства
24 | браузера, такая программа позволяет в явном виде указывать, какой запрос, с какими параметрами, заголовками и
25 | телом мы хотим отправить. Дополнительно она может содержать возможность сохранения определенных конфигураций
26 | запросов, функциональность для совместной работы нескольких пользователей и т.д. При этом представлена такая
27 | программа может быть как консольным или десктопным приложением, так и обычным плагином для браузера - ведь браузер
28 | умеет все то же самое, просто его базовые возможности не направлены на то, чтобы делать это вручную.
29 | 2. Компонент языка программирования. Например, Java-класс или Java-библиотека, которая позволяет конфигурировать и
30 | отправлять запросы. Это может быть полезно как для клиентских приложений (в JavaScript или десктопных/мобильных
31 | приложениях, взаимодействующих с сервером), так и для серверных программ - для межсерверной коммуникации. Кроме
32 | того, автоматизированные тесты тоже требуют использования HTTP-клиентов для тестирования API.
33 |
34 | Возможно, мы еще столкнемся с HTTP-клиентами в Java, но сегодняшняя статья больше направлена на знакомство с
35 | клиентами в первой интерпретации. Ниже представлены несколько из них.
36 |
37 | ## Swagger
38 |
39 | Строго говоря, именно Swagger не является HTTP-клиентом в принципе. Это скорее набор инструментов, которые позволяют
40 | описывать (документировать) HTTP-запросы и просматривать их описание в удобном формате.
41 |
42 | Как раз с изучением документации запросов с помощью Swagger вы столкнетесь в практической части. Но есть еще один
43 | важный момент: если серверное приложение использует специализированную библиотеку, это позволяет открыть
44 | документацию запросов прямо в браузере, обратившись по специальному адресу в этом приложении. И там же отправлять
45 | эти запросы в удобном формате - вплоть до предустановленных схем параметров и значений определенных параметров в
46 | соответствии с прописанными на сервере правилами.
47 |
48 | Таким образом, Swagger позволяет эмулировать в браузере HTTP-клиент для отдельно взятого серверного приложения.
49 | Может звучать запутанно, но все станет понятнее после начала выполнения практического задания.
50 |
51 | В целом, я не рекомендую ограничиваться знакомством только со Swagger, воспринимая его в первую очередь как
52 | инструмент для чтения документации к HTTP-запросам.
53 |
54 | ## cURL
55 |
56 | cURL (или curl) - консольный HTTP-клиент. В силу отсутствия GUI он не очень удобен в работе, по сравнению с
57 | альтернативными решениями, но имеет ряд неоспоримых преимуществ:
58 |
59 | 1. Консольный интерфейс. Если вам необходимо отправить простой запрос и/или ваша работа тесно связана с командной
60 | строкой (сисадмины, девопсы и другие) - использование консольного инструмента банально быстрее, чем любое решение
61 | с GUI;
62 | 2. Наглядность. Безусловно, при частом использовании HTTP-клиента не хочется тратить время на однотипные действия
63 | или сталкиваться с неудобным интерфейсом - GUI здесь часто выигрывает у консольных программ. Но оформление
64 | запроса в cURL позволяет намного лучше понять содержимое HTTP-запросов - описанный в cURL запрос лаконично
65 | отображает все содержимое в виде текста. Кроме того, это позволяет новичкам лучше запомнить составные части
66 | запроса;
67 | 3. Удобный формат для передачи запроса. Не так редко возникают ситуации, когда при тестировании API находят ошибки,
68 | воспроизводимые для конкретного набора параметров. Именно возможность представить запрос в виде обычного
69 | человекочитаемого текста является большим достижением данного клиента. В случае с графическими клиентами
70 | содержимое запроса может быть разбросано по множеству элементов программы, что затрудняет передачу конфигурации
71 | запроса другому специалисту.
72 |
73 | > *Справедливости ради, многие десктопные приложения решают эту проблему через возможность экспортировать запрос...
74 | > Например, в формате cURL:)
75 |
76 | В этой статье мы не будем подробно разбирать работу с каждым рассматриваемым инструментом - они достаточно просты
77 | для самостоятельного освоения. Кроме того, в случае с cURL пример сгенерированного запроса для практической части можно
78 | будет посмотреть в Swagger - там есть специальное поле, отображающее, как каждый выполняемый запрос выглядел бы в cURL.
79 |
80 | Ознакомиться с общими принципами формирования можно, например, здесь:
81 | [ссылка](https://docs.oracle.com/en/cloud/saas/marketing/eloqua-develop/Developers/GettingStarted/APIRequests/curl-formats.htm).
82 |
83 | Скачать cURL для вашей операционной системы можно [здесь](https://curl.se/download.html). Для некоторых ОС (включая
84 | Windows 10 и выше) он является предустановленным.
85 |
86 | Пример POST-запроса в cURL для Windows:
87 |
88 | В зависимости от ОС могут быть незначительные отличия в оформлении. В т.ч. из-за различных правил оформления,
89 | например, переносов строк:
90 |
91 | ```cmd
92 | curl -X POST "http://localhost:8080/private/v1/car" ^
93 | -H "accept: */*" ^
94 | -H "Content-Type: application/json" ^
95 | -d "{\"brandId\": \"string\", \"year\": 1900, \"model\": \"string\", \"color\": \"string\", \"number\": \"string\", \"actualTechnicalInspection\": true}"
96 | ```
97 |
98 | ## Postman
99 |
100 | Postman - наиболее популярный из инструментов для отправки запросов с графическим интерфейсом. Его, среди прочих,
101 | часто используют мануальные тестировщики.
102 |
103 | Существует как в десктопном формате, так и веб-версия: [ссылка](https://www.postman.com/downloads/).
104 |
105 | Большой плюс Postman в том, что он предлагает возможность сохранять запросы для повторного использования, объединять
106 | их в "коллекции" по логическим группам, делиться такими коллекциями и т.д. К сожалению, часть функционала является
107 | платной, но для большинства задач с запасом хватает бесплатного режима.
108 |
109 | В целом, это один из наиболее дружелюбных и популярных инструментов для работы с HTTP-запросами на данный момент.
110 | Как за счет предлагаемых возможностей, так и благодаря интуитивно-понятному интерфейсу.
111 |
112 | ## IDEA HTTP Client
113 |
114 | Да, возможность отправлять HTTP-запросы есть и в IntelliJ IDEA. К сожалению, только в Ultimate-версии.
115 |
116 | Подробности можно найти [здесь](https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html).
117 |
118 | Вкратце суть взаимодействия сводится к созданию файлов в формате `.http` и описании в них запросов в упрощенном виде -
119 | чем-то напоминающем тот, в котором они были описывались в первых статьях, посвященных HTTP. Ниже предствален пример
120 | содержимого такого http-файла:
121 |
122 | ```http request
123 | POST http://localhost:8080/private/v1/car
124 | accept: */*
125 | Content-Type: application/json
126 |
127 | {
128 | "brandId": "string",
129 | "year": 1900,
130 | "model": "string",
131 | "color": "string",
132 | "number": "string",
133 | "actualTechnicalInspection": true
134 | }
135 | ```
136 |
137 | Если к этому формату добавить характерные флаги - он окажется крайне похожим на формат, используемый cURL. Также
138 | IDEA умеет воспринимать и оригинальный cURL формат (и Postman-коллекции), с конвертацией к виду выше.
139 |
140 | Все подробности можно найти по приложенной ранее ссылке. Также в самой IDEA можно посмотреть примеры различных
141 | запросов после создания файла `.http`.
142 |
143 | В целом, не могу назвать этот инструмент популярным, но для локального использования он вполне удобен. Особенно если
144 | рассматривать его как более дружелюбный вариант cURL для базовых нужд.
145 |
146 | ## Заключение
147 |
148 | Основные из описанных сегодня инструментов - cURL и Postman - весьма обширны по возможностям - намного шире, чем
149 | описано в этой статье. Те из читателей, кто работает в смежных с разработкой областях, могут знать об этом не
150 | понаслышке. Однако цель этой статьи - дать общую информацию об инструментах тем, кто лишь недавно начал знакомство с
151 | HTTP.
152 |
153 | В силу этого текст сделан максимально облегченным и наиболее важной его частью является практическая составляющая -
154 | как изучение самих HTTP-клиентов, так и взаимодействие с предложенным ниже приложением.
155 |
156 | #### С теорией на сегодня все!
157 |
158 | 
159 |
160 | Переходим к практике:
161 |
162 | ## Задача
163 |
164 | Репозиторий для практики представлен по [ссылке](https://github.com/KFalcon2022/test-http-client).
165 |
166 | В readme-файле к нему можно найти инструкцию по запуску и описание задачи. Отдельно отмечу, что знакомство с кодовой
167 | базой остается на ваше усмотрение - в ней использовано много пока незнакомых нам технологий. Основная задача
168 | приложения - дать вам возможность почувствовать принципы работы клиент-серверного приложения со стороны клиента.
169 |
170 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
171 | >
172 | > Канал: https://t.me/ViamSupervadetVadens
173 | >
174 | > Мой тг: https://t.me/ironicMotherfucker
175 | >
176 | > **Дорогу осилит идущий!**
177 |
178 |
--------------------------------------------------------------------------------
/lessons/jdbc/128/JDBC introduction. Connection.md:
--------------------------------------------------------------------------------
1 | # Что такое JDBC. Подключение к БД. Connection
2 |
3 | Эта статья открывает раздел, посвященный взаимодействию с БД через Java-приложение. Так, в ближайших уроках мы
4 | рассмотрим основной механизм работы с реляционными базами данных через Java, познакомимся с основными инструментами,
5 | используемыми при взаимодействии с БД.
6 |
7 | Практическая ценность этой информации в коммерческой разработке не слишком высока - шанс, что вы будете использовать
8 | именно этот API в реальных проектах невелик. Но именно на базе изученной библиотеки работает абсолютное большинство
9 | более высокоуровневых решений, с некоторыми из которых мы познакомимся в следующих разделах. А значит - сталкиваются
10 | с теми же ограничениями и используют те же инструменты, которые мы будем изучать.
11 |
12 | Основной целью раздела мне видится не столько знакомство с отдельными классами и методами, сколько разъяснение основ
13 | взаимодействия с базами данных и ряда других специфических аспектов. Наконец, я надеюсь помочь вам избежать
14 | магического мышления и сформировать фундамент, который позволит подходить к более продвинутым инструментам системно -
15 | именно этого не хватает большинству junior-специалистов.
16 |
17 | ## JDBC
18 |
19 | При работе с базами данных через Java можно заметить ту же тенденцию, что и при работе с БД через любой другой
20 | клиент: существует единый API для взаимодействия с реляционными базами данных (его же поддерживают и некоторые
21 | NoSQL БД), а вот большинство реализаций NoSQL предоставляют собственные API и клиенты, которые обычно сильно
22 | отличаются друг от друга.
23 |
24 | Это является логичным следствием того, что механизмом взаимодействия с реляционными БД является SQL, в то время как
25 | практически каждая реализация NoSQL предоставляет собственное API, не всегда оформленное в виде языка в привычном
26 | понимании.
27 |
28 | В основном курсе мы не будем углубляться в детали работы с NoSQL БД, вместо этого сфокусируемся на реляционных базах
29 | данных.
30 |
31 | **JDBC** - _Java DataBase Connectivity_ - часть стандартной библиотеки Java, предоставляющие единый стандарт и,
32 | одновременно, публичный API для работы с реляционными базами данных. Кодовая база JDBC содержится в пакете `java.sql`.
33 |
34 | Сам по себе JDBC не умеет работать ни с одной из БД. Она лишь предоставляет основные интерфейсы*, которые
35 | будет использовать Java-разработчик для взаимодействия с базами данных.
36 |
37 | > *Рекомендую открыть содержимое пакета `java.sql` посмотреть хотя бы список файлов в нем.
38 | >
39 | > Конечно, кроме интерфейсов там есть и классы. Но они несут общее или вспомогательное назначение: классы исключений,
40 | > констант (в т.ч. енамы) и подобное. Если не ошибаюсь, там есть единственный значимый класс с собственным
41 | > поведением, но о нем позже.
42 |
43 | В свою очередь реальные механизмы взаимодействия с конкретной базой данных предоставлены в **драйверах** - библиотеках
44 | с имплементациями интерфейсов из `java.sql`, которые будут учитывать специфику конкретной СУБД, содержать механизм
45 | доставки запросов к ней и прочее. Как правило, драйверы поставляются разработчиками самой СУБД.
46 |
47 | При этом Java-разработчик практически никогда не работает с драйвером напрямую - лишь добавляет его в свой проект. Т.
48 | е., по сути, лишь указывает нужную зависимость в Maven- или Gradle-конфигурации. А взаимодействие на уровне кода
49 | сводится к использованию интерфейсов JDBC, чьи имплементации из драйвера будут использованы во время выполнения
50 | программы.
51 |
52 | В этом и заключается основное различие во взаимодействии с РСУБД и NoSQL, драйверы* которого обычно не имплементируют
53 | JDBC. В результате чего работа с каждой новой NoSQL БД требует еще и изучения новой Java-библиотеки со своим API и
54 | своими ограничениями.
55 |
56 | > *Обычно такие библиотеки называют клиентами, но я не вижу смысла объяснять разницу этих терминов в обзорной статье.
57 |
58 | Подводя краткий итог, ближайшие статьи будут посвящены ключевым интерфейсам JDBC и правилам их использования.
59 | Конечные реализации этих интерфейсов мы затрагивать не будем - их особенности никак не влияют на наш код.
60 |
61 | ## Подключение к БД из Java-приложения
62 |
63 | Пришло время вспомнить нашу тестовую базу данных, развернутую в PostgreSQL. Именно ее мы возьмем за основу для
64 | дальнейших примеров и практических задач. Разница лишь в том, что теперь мы будем обращаться к ней из Java-приложения.
65 |
66 | Из этого логично следует, что нам требуется Java-приложение и драйвер для работы с PostgreSQL.
67 |
68 | Для демонстрации и практики будем использовать этот репозиторий:
69 | [ссылка](https://github.com/KFalcon2022/jdbc-practical-tasks).
70 |
71 | Подключить драйвер достаточно просто. Ищем JDBC-драйвер для PostgreSQL и используем свежую версию:
72 |
73 | ```groovy
74 | runtimeOnly 'org.postgresql:postgresql:42.7.1'
75 | ```
76 |
77 | Обратите внимание, что использована конфигурация `runtimeOnly`.
78 | [mvnrepository](https://mvnrepository.com/artifact/org.postgresql/postgresql/42.7.1), вероятно, предложит вам
79 | стандартную конфигурацию `implementation`, но для драйвера в ней нет необходимости - на этапе компиляции нам
80 | достаточно интерфейсов JDBC, а сама реализация нужна только для этапа выполнения. Это справедливо вне зависимости от
81 | СУБД, с которой вы будете работать. По крайней мере, пока вы используете JDBC*.
82 |
83 | > *JDBC предоставляет единый интерфейс для доступа к РСУБД. Единый, но не единственный.
84 | >
85 | > Распространенным примерам альтернативного подхода может быть, например R2DBC - это альтернативная спецификация для
86 | > работы с базами данных, актуальная для проектов с реактивным стеком. Детали нас интересуют мало, главное - работа
87 | > даже с реляционными базами данных не всегда завязана на JDBC, хоть он и остается решением по-умолчанию.
88 | >
89 | > И, например, R2DBC-драйвер для PostgreSQL обычно добавляют в проект как `implementation`, не отделяя драйвер от
90 | > спецификации (поставляется транзитивно). Этого можно избежать, но углубляться в эту тему не будем.
91 |
92 | По сути, сразу после этого мы имеем на руках приложение, которое может взаимодействовать с базой данных. Осталось
93 | разобраться, каким образом.
94 |
95 | ## Connection
96 |
97 | Ключевым интерфейсом при работе с JDBC является `Connection`. Он представляет собой отражение пользовательской
98 | сессии к БД.
99 |
100 | Так или иначе, все взаимодействие с БД будет сводиться к работе с объектом (или объектами) `Connection` - он
101 | инкапсулирует все API для отправки SQL-запросов, работы с транзакциями, содержит настройки самого подключения. Все
102 | остальные интерфейсы, которые нам потребуются, будут предоставляться именно через `Connection`.
103 |
104 | Единственная проблема - нельзя просто взять, и создать объект `Connection` вручную. Хотя бы потому что это интерфейс,
105 | а его имплементация будет доступна лишь во время выполнения. А значит, нам нужен некий класс, который будет отвечать
106 | за создание `Connection`.
107 |
108 | JDBC предоставляет такой класс - `DriverManager`. Это тот единственный класс с собственным поведением, о котором
109 | упоминалось выше.
110 |
111 | Через механизмы Java Reflection (мы кратко упоминали его в прошлом уроке) этот класс получит доступы к драйверам и
112 | реализациям `Connection` во время выполнения и сможет создать интересующие нас объекты. На этапе написания код нам
113 | остается лишь использовать методы самого `DriverManager`.
114 |
115 | Опуская ряд вспомогательных методов для настройки `DriverManager`, его API сводится к нескольким перегрузкам метода
116 | `getConnection()`.
117 |
118 | Проще всего нам будет работать с тем, который принимает адрес СУБД (мы с ним сталкивались при работе с БД
119 | через другие клиенты), логин и пароль пользователя.
120 |
121 | Так, получение объекта `Connection` в коде сводится к примерно такой записи:
122 |
123 | ```java
124 | try (Connection connection = DriverManager.getConnection(
125 | "jdbc:postgresql://localhost:5432/test_db",
126 | "postgres",
127 | "postgres")) {
128 | // Дальнейшая работа с БД через connection
129 | } catch (SQLException e) {
130 | log.error(e);
131 | }
132 | ```
133 |
134 | Полагаю, логин и пароль вопросов не вызывают. Но стоит разобраться с `url` (имя первого параметра
135 | `DriverManager.getConnection`) и почему-то появившимся `try-with-resources`.
136 |
137 | С URL все просто. Стандартная для JDBC маска выглядит примерно так: `jdbc:%subprotocol%:%subname%`.
138 |
139 | `%subprotocol%` - по сути, это указание драйвера, который будет использован. В зависимости от него могут быть
140 | различные правила к формированию `%subname%`. В случае с PostgreSQL - драйвер обозначается как `postgresql`.
141 |
142 | `%subname%` - эта часть может содержать различные данные в различном формате - в зависимости от СУБД и способа
143 | подключения. Так или иначе, здесь должна содержаться "ссылка" - адрес БД с сети. В разделе, посвященном Web, мы
144 | будем чуть детальнее разбирать тему адресации. В нашем случае это адрес СУБД: `localhost:5432/` и путь до
145 | интересующей нас БД: `test_db`. Последний можно не указывать - тогда Connection будет создан для СУБД, без четкой
146 | привязки к определенной базе данных.
147 |
148 | Теперь, почему `try-with-resources`. Поскольку `Connection` отражает физическое подключение к СУБД, он, как и любой
149 | объект, отражающий подключение к внешнему ресурсу, реализует `AutoCloseable`. А значит требует закрытия.
150 | Соответственно, должен либо создаваться в `try-with-resources`, либо потребуется явно вызывать `close()` после
151 | завершения работы с ним.
152 |
153 | И, наконец, catch-блок. В нем содержится обработка `SQLException` - базового исключения при работе с БД. Опять же, в
154 | силу того, что мы пытаемся получить доступ к внешнему ресурсу - нам нужен механизм оповещения на случай, если не
155 | удалось достучаться до самого ресурса, или возникли какие-то проблемы при дальнейшем взаимодействии. Стандартным для
156 | Java инструментом в подобных ситуациях выступает checked-исключение.
157 |
158 | По сути, `SQLException` - аналог известного нам `IOException`, но для работы с БД*.
159 |
160 | > *Обратите внимание: `SQLException` НЕ наследует `IOException`, как можно было бы подумать. Каждый из них дает
161 | > начало своей иерархии исключений, но сами по себе они являются прямыми наследниками `Exception`.
162 |
163 | На этом завершаем обзорное знакомство с JDBC. Конкретные инструменты для работы с БД будем разбирать в следующих
164 | статьях. Там же будет и практика.
165 |
166 |
167 | #### На сегодня все!
168 |
169 | Практика так же будет в следующей статье.
170 |
171 | 
172 |
173 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
174 | >
175 | > Канал: https://t.me/ViamSupervadetVadens
176 | >
177 | > Мой тг: https://t.me/ironicMotherfucker
178 | >
179 | > **Дорогу осилит идущий!**
180 |
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/122/Gradle. Dependencies.md:
--------------------------------------------------------------------------------
1 | # Gradle. Работа с Зависимостями
2 |
3 | В рамках сегодняшней статьи базово познакомимся со спецификой Gradle в работе с зависимостями.
4 |
5 | В отличие от прошлой статьи, здесь не будет какой-то концептуальной разницы с Maven. Несмотря на то, что подходы
6 | Maven и Gradle к работе с зависимостями существенно отличаются, идея работы с внешними библиотеками через зависимости
7 | от артефактов, доступ к которым обеспечен через локальные и удаленные репозитории, идентична в обеих системах сборки.
8 | Поскольку целью статьи является знакомство - в первую очередь, сконцентрируемся на терминологии, синтаксисе и тех
9 | аспектах, которые актуальны для новичков на практике.
10 |
11 | Как и в других темах, здесь будут просматриваться две характерные для Gradle тенденции:
12 |
13 | 1. Gradle предлагает большую гибкость в сравнении с Maven. Вплоть до возможности определить собственные операторы (в
14 | рамках Gradle они называются **конфигурациями***, этот термин будет активно использоваться ниже) с необходимой
15 | спецификой, которую не предоставляют стандартные конфигурации. Но в эту область в рамках курса погружаться не
16 | будем - она нужна не часто, а для начинающих специалистов будет, скорее всего, бесполезна на практике;
17 | 2. Из-за п.1 существуют более и менее актуальные конфигурации, не все из которых доступны в отдельно
18 | взятой версии Gradle. Кроме того, гибкость и привязанность функциональности к плагинам (особенно Core-плагинам)
19 | приводит к тому, что конфигурации в различных плагинах тоже могут отличаться. Поэтому информация из данной статьи
20 | актуальна, в первую очередь, для приложений с использованием плагина `java` и Gradle 8.5.
21 |
22 | > *`Configuration` - объект Gradle, который отвечает за работу с зависимостями. В рамках Gradle-проекта может быть
23 | > (и обычно есть) несколько экземпляров этого объекта, каждый из которых содержит свои настройки - на каком этапе
24 | > жизненного цикла проекта должны быть доступны зависимости (этому посвящен следующий пункт), доступность транзитивных
25 | > зависимостей и пр.
26 |
27 | ## Classpath
28 |
29 | При знакомстве с Maven мы выделяли три этапа жизненного цикла приложения, к которым можно отчасти привязать скоупы
30 | зависимостей: компиляция, тестирование и выполнение.
31 |
32 | Gradle в этой области оперирует понятием _classpath_ - мы уже сталкивались с этим термином в контексте Java. В Gradle
33 | определяется несколько classpath'ов и они являются логической надстройкой - это не переменная окружения с путем до
34 | физического расположения нужных классов/библиотек, как в Java, а конфигурация, которая определяет отношение
35 | конкретных зависимостей к конкретному этапу жизненного цикла приложения. При этом физическое расположение самих
36 | классов зависимостей этой абстракцией не регулируется.
37 |
38 | Для Gradle (с Java-плагином) характерно выделение четырех classpath'ов:
39 |
40 | 1. `compileClasspath`. Хранит зависимости, необходимые для компиляции проекта. В целом, идентичен зависимостям этапа
41 | компиляции в Maven. Речь именно об этапе жизненного цикла, а не compile scope - концепция scope ближе к понятию
42 | конфигурации в Gradle и о ней мы поговорим чуть позже;
43 | 2. `runtimeClasspath`. Хранит зависимости, необходимые на этапе выполнения проекта. Идентичен зависимостям этапа
44 | выполнения в Maven. В большинстве случаев, зависимость нужна и для этапа компиляции, и для этапа выполнения,
45 | поэтому добавляется в оба скоупа. Но не всегда;
46 | 3. `testCompileClasspath`. То же самое, что и `compileClasspath`, но для компиляции исходного кода тестов;
47 | 4. `testRuntimeClasspath`. Полагаю, логика очевидна. Зависимости, необходимые для исполнения тестов.
48 |
49 | Конечно, на практике большинство зависимостей должно быть доступно на нескольких или всех этапах жизни проекта,
50 | из-за чего большинство конфигураций предполагает добавление зависимости сразу в несколько classpath'ов.
51 |
52 | Стандартным для Java-проектов конфигурациям посвящен следующий пункт.
53 |
54 | ## Стандартные конфигурации и синтаксис
55 |
56 | В целом, этот пункт достаточно хорошо описан в документации к Java-плагину, поэтому текст пункта основан,
57 | преимущественно, на ней:
58 | [документация](https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_plugin_and_dependency_management).
59 |
60 | 
61 |
62 | Нас интересуют конфигурации, обозначенные зелеными треугольниками. На самом деле их больше, но именно эти являются
63 | наиболее актуальными и рекомендуемыми к использованию на момент написания статьи.
64 |
65 | `compileOnly` и `runtimeOnly` - конфигурации, которые добавляют зависимость только в `compileClasspath` или
66 | `runtimeClasspath` (и `testRuntimeClasspath`) соответственно. Также в соответствующие classpath'ы добавляются
67 | транзитивные зависимости.
68 |
69 | Использование `compileOnly`, в целом, очень похож на scope `provided` в Maven. Целесообразность использования этой
70 | конфигурации на практике - вопрос достаточно спорный. Если не уходить в совсем узкие сценарии использования - иногда
71 | `compileOnly` используется в библиотеках, особенно для ситуаций, когда в runtime-могут быть использованы несколько
72 | различных библиотек, реализующих одно API (как, например, реализации логгеров под API SLF4J). Основное преимущество
73 | использования этой конфигурации - меньший размер сборки. Но, во-первых, это преимущество далеко не всегда можно
74 | реализовать, во-вторых - в случае с back-end-разработкой оно не особо важно. Как правило, экономия пары мегабайт
75 | (что для скомпилированной библиотеки достаточно много) на диске сервера не играет какой-либо роли.
76 |
77 | `runtimeOnly` - пример использования можно развить из предыдущего. На уровне конечного приложения (например,
78 | использующего библиотеку из предыдущего примера) нам уже нужна реализация конкретного логгера на этапе исполнения -
79 | в таком случае, эту реализацию можно добавить с помощью `runtimeOnly`. Но на практике эта конфигурация встречается
80 | редко.
81 |
82 | Обратите внимание, что `runtimeOnly` добавляет зависимость (вместе с транзитивными) в оба runtime-classpath'а, в то
83 | время как `compileOnly` - только в `compileClasspath`.
84 |
85 | `implementation` - основная конфигурация для добавления зависимостей. Добавляет указанную зависимость и ее
86 | транзитивные зависимости во все четыре classpath'а. Для Gradle-проектов, не являющихся библиотеками, именно эта
87 | конфигурация будет наиболее популярной.
88 |
89 | > **!NB**: При разработке библиотек или Gradle-проектов, подключаемых в другие Gradle-проекты (по факту, тех же
90 | > библиотек, но уровня конкретных проектов) может использоваться, но только в случае, если эта библиотека не должна
91 | > поставлять в подключаемый проект своих транзитивных зависимостей (т.е. их потребуется подключить вручную). Если же
92 | > библиотека должна поставлять и собственные транзитивные зависимости, что встречается намного чаще - обычно используют
93 | > конфигурацию `api` из плагина `java-library`. Но это не относится к теме текущей статьи.
94 |
95 | Кроме описанных конфигураций в Java-плагине существует еще несколько конфигураций для подключения зависимостей в
96 | тесты - это особенно актуально для специализированных тестовых библиотек, но иногда таким образом подключаются и
97 | другие зависимости - например, в тестах для проектов-библиотек (если не используется `api`) или если зависимость не
98 | нужна в самом проекте.
99 |
100 | 
101 |
102 | На схеме выше можно увидеть три новых конфигурации: `testCompileOnly`, `testRuntimeOnly` и `testImplementation`.
103 |
104 | Также становится понятно, почему `runtimeOnly` и `implementation` добавляют свои зависимости в test-classpath'ы -
105 | они являются наследниками `testRuntimeOnly` и `testImplementation` соответственно.
106 |
107 | В целом, логика очевидна: `testCompileOnly` добавляет зависимости в `testCompileClasspath`, `testRuntimeOnly` - в
108 | `testRuntimeClasspath`, `testImplementation` - в оба тестовых classpath'а.
109 |
110 | На практике, по крайней мере, на первых этапах, рекомендую ограничиться использованием `testImplementation` - к
111 | оставшимся двум конфигурациям обратиться только если первой окажется недостаточно. Тестовые зависимости намного
112 | менее критичны, чем основные, и углубляться в их тонкую конфигурацию обычно избыточно.
113 |
114 | Теперь, ознакомившись с основными конфигурациями разберем синтаксис их применения. Традиционно для Gradle есть как
115 | минимум два варианта.
116 | Полный:
117 |
118 | ```groovy
119 | dependencies {
120 | implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.20.0'
121 | // ...
122 | }
123 | ```
124 |
125 | И сокращенный:
126 |
127 | ```groovy
128 | dependencies {
129 | implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
130 | // ...
131 | }
132 | ```
133 |
134 | В обоих случаях зависимости указываются в блоке `dependencies` (есть и иные варианты, но они менее популярны).
135 | Указывается используемая конфигурация, после чего перечисляются атрибуты зависимости. Как правило, используются
136 | основные три, знакомые нам еще по Maven: `groupId`, `artifactId` (в полной версии указывается как `name`), `version`.
137 | При этом в полной форме записи атрибуты указываются с названиями и перечисляются через запятую, а в сокращенной -
138 | разделяются лишь двоеточием, при этом записываются как единая строка.
139 |
140 | Фактически, данный синтаксис покрывает 99% сценариев подключения зависимостей. Оставшийся процент остается на
141 | указание специфических атрибутов или иных тонких настроек. Из таких мы рассмотрим только пример синтаксиса для
142 | исключения транзитивной зависимости.
143 |
144 | Для примера возьмем зависимость `A` с транзитивной зависимостью `B` (как в аналогичном примере для Maven).
145 | Исключение зависимости в общем виде будет выглядеть так:
146 |
147 | ```groovy
148 | dependencies {
149 | implementation('com.some.group:A:6.6.6') {
150 | exclude group: 'com.another.group', module: 'excluded-artifact'
151 | }
152 | // ...
153 | }
154 | ```
155 |
156 | В данном случае во все classpath'ы будет добавлена зависимость `'com.some.group:A:6.6.6'`, но без транзитивной
157 | `'com.another.group:excluded-artifact'`.
158 |
159 | ## Заключение
160 |
161 | В рамках данной статьи мы разобрали наиболее базовые инструменты для работы с зависимостями в Gradle. Конечно, этого
162 | недостаточно, чтобы работать с Gradle эффективно и использовать его на полную мощность. Но это та основа, которая
163 | позволит использовать данную систему сборки в собственных пет-проектах и не потеряться в случае, если попадется
164 | коммерческий проект с использованием Gradle. В последнем случае, скорее всего, файлы сборки смогут ввергнуть в ужас
165 | и далеко не все в них будет понятно. Но даже в этом случае вы сможете выхватить ключевые моменты и, как минимум,
166 | сможете понять, что гуглить, чтобы разобраться с остальным:)
167 |
168 | #### На сегодня все!
169 |
170 | 
171 |
172 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
173 | >
174 | > Канал: https://t.me/ViamSupervadetVadens
175 | >
176 | > Мой тг: https://t.me/ironicMotherfucker
177 | >
178 | > **Дорогу осилит идущий!**
179 |
--------------------------------------------------------------------------------
/lessons/libraries-and-build-systems/123/Gradle Wrapper. What's next.md:
--------------------------------------------------------------------------------
1 | # Gradle. Знакомство с Gradle Wrapper. Что дальше?
2 |
3 | Данная статья будет заключительной для подраздела "Gradle" и для раздела "Системы сборки" в целом. В ней мы ближе
4 | познакомимся с Gradle Wrapper, который неоднократно упоминался в предыдущих статьях и рассмотрим направления для
5 | дальнейшего изучения Gradle.
6 |
7 | ## Gradle Wrapper
8 |
9 | В силу того, что различные проекты могут быть написаны с использованием различных, в том числе не совместимых, версий
10 | Gradle и при этом такие проекты вполне могут оказаться одновременно на компьютере конкретного разработчика - логично
11 | использовать инструмент, который позволит работать с этими системами сборки без установки и конфигурации каждой
12 | конкретной версии вручную. Тем более, установка Gradle предполагает в т.ч. определение переменных окружения
13 | (`GRADLE_HOME`, `PATH`), что еще больше затрудняет установку и взаимодействие с несколькими версиями Gradle в рамках
14 | одной машины.
15 |
16 | Именно таким инструментом и является Gradle Wrapper. Он позволяет как работать с Gradle конкретной версии через
17 | консоль, не устанавливая эту версию в полном смысле слова, так и автоматизирует процесс "установки" и обновления
18 | (установки новой версии) конкретной версии Gradle для конкретного проекта.
19 |
20 | ### Состав Gradle Wrapper
21 |
22 | При знакомстве со структурой Gradle-проекта, мы уже разбирали, из чего состоит Gradle Wrapper. Тезисно повторим эти
23 | моменты:
24 |
25 | 1. `gradle-wrapper.properties`. Файл с настройками для Gradle Wrapper, лежит в директории
26 | `${projectHome}/gradle/wrapper`. Нас, как правило, интересует `distributionUrl` - путь для скачивания конкретной
27 | версии Gradle. Именно в пути этого файла можно увидеть (и поправить, если надо) версию Gradle, которую будет
28 | использовать Gradle Wrapper в данном проекте. Остальные настройки представляют меньший интерес на данном этапе.
29 | Подробнее здесь: [документация](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:adding_wrapper);
30 | 2. `gradle-wrapper.jar`. Находится в той же директории, что и `gradle-wrapper.properties`. Скрипты для установки
31 | конкретной версии Gradle на основании файла настроек;
32 | 3. `gradlew` и `gradlew.bat`. Находятся в корневой директории проекта. Скрипты для работы с Wrapper'ом. Для
33 | UNIX-подобных (MacOS, Linux и т.д.) систем и Windows соответственно.
34 |
35 | ### Создание Wrapper'а
36 |
37 | Строго говоря, Wrapper не является обязательной частью Gradle-проекта, хоть обычно и создается по умолчанию, в т.ч.
38 | при создании проекта через IDEA. Де-факто, создание Gradle Wrapper - результат работы Gradle-таски `wrapper`. Таким
39 | образом, создание Wrapper'а для работы с различными версиями Gradle требует установки на компьютер Gradle хоть
40 | какой-нибудь версии. Зачастую, это берет на себя IDE, тем самым лишая этот процесс наглядности. Но всегда можно
41 | попробовать сделать это вручную.
42 |
43 | В данной статье этот пункт больше направлен на то, чтобы объяснить, что создание Wrapper'а - условно-ручная,
44 | конфигурируемая опция. Т.е. при вызове `gradle wrapper` в консоли можно указать набор параметров для Wrapper'а. В
45 | документации по ссылке выше есть перечень параметров, которые можно указать.
46 |
47 | ### Использование
48 |
49 | С точки зрения использования Gradle Wrapper на практике, синтаксис практически идентичен использованию Gradle через
50 | консольный интерфейс. И во многом подобен работе с Maven через `mvn`. Таким образом, информацию из данного пункта можно
51 | использовать как для работы с Wrapper'ом, так и для работы с установленным Gradle. Разница будет только в
52 | используемой команде.
53 |
54 | Обращение к установленному Gradle (вне зависимости от ОС):
55 |
56 | ```shell
57 | > gradle
58 | ```
59 |
60 | Обращение к Gradle Wrapper в UNIX-подобных системах (запуск Shell-скрипта):
61 |
62 | ```shell
63 | > ./gradlew
64 | ```
65 |
66 | Обращение к Gradle Wrapper в Windows (запуск bat):
67 |
68 | ```shell
69 | > gradle.bat
70 | ```
71 |
72 | После этого, подобно использованию `mvn`, мы можем указать цепочку тасок, которые должны быть выполнены.
73 | Единственное, что стоит помнить - таски в Gradle могут быть выполнены в порядке, отличном от указанного в консоли,
74 | если между этими тасками есть отношения `mustRunAfter` или `shouldRunAfter`.
75 |
76 | Простейший пример вызова таски `build` для Gradle-проекта с помощью Gradle Wrapper:
77 |
78 | ```shell
79 | > ./gradlew build
80 | ```
81 |
82 | Также перед названием задачи может использоваться префикс ":":
83 |
84 | ```shell
85 | > ./gradlew :build
86 | ```
87 |
88 | ":" - указатель на проект (или подпроект), для которого выполняется таска. Например, если наш проект `gradle-sample`
89 | имеет дочерний проект (в терминах Maven - модуль) - `gradle-subproject`, то мы можем выполнить сборку только
90 | проекта `gradle-subproject` с помощью следующей команды:
91 |
92 | ```shell
93 | > ./gradlew gradle-subproject:build
94 | ```
95 |
96 | Или аналогичной с ":":
97 |
98 | ```shell
99 | > ./gradlew :gradle-subproject:build
100 | ```
101 |
102 | Использование ":" в начале можно воспринимать как "корневой проект:". Т.е. обращение `:gradle-subproject:build`
103 | звучит как "_Выполни задачу `build` для проекта по пути 'корневой проект:gradle-subproject_". И отсюда следует
104 | достаточно важное различие в сборке с указанием ":" и без.
105 |
106 | Если мы в подобном проекте, содержащем подпроект, вызовем
107 |
108 | ```shell
109 | > ./gradlew build
110 | ```
111 |
112 | То будет выполнена сборка как для основного проекта (`gradle-sample`), так и для подпроекта `gradle-subproject`.
113 |
114 | Но если мы вызовем
115 |
116 | ```shell
117 | > ./gradlew :build
118 | ```
119 |
120 | То задача будет выполнена сборка только для `gradle-sample`. А `gradle-subproject` будет проигнорирован. Потому что
121 | `:build` можно трактовать как "выполни команду `корневой проект:build`"*.
122 |
123 | > *Стоит понимать, что идея расшифровки ":" в начале задачи как "корневой проект:" - лишь удобный способ запомнить
124 | > отличие обращения к таске с использованием ":" и без него на начальном этапе работы. Сам Gradle не вкладывает такого
125 | > смысла. Но в момент, когда вы столкнетесь с некорректностью этой аналогии - полагаю, она уже не будет вам нужна:)
126 |
127 | Как говорилось выше, можно вызывать цепочку задач:
128 |
129 | ```shell
130 | > ./gradlew clean build
131 | ```
132 |
133 | И, наконец, использовать различные параметры для задач - как специфичные для задачи, так и общие, определяемые
134 | Gradle (использование кэша, приндутельный запуск, исключение задачи и другие):
135 |
136 | ```shell
137 | > ./gradlew sthTask --sth-option-with-value=sthValue
138 | ```
139 |
140 | ```shell
141 | > ./gradlew sthTask --sth-option-without-value
142 | ```
143 |
144 | На мой взгляд, это достаточный базис синтаксиса для работы с Gradle (или Gradle Wrapper) через консольный интерфейс,
145 | достаточный для первых лет разработки. И позволяющий более осознанно и гибко использовать IDEA для работы с Gradle -
146 | ведь это, по сути, лишь обертка над консольным интерфейсом.
147 |
148 | Со временем, особенно при плотной работе с Gradle, придется углубиться и выйти за пределы данной статьи. Но, полагаю,
149 | к этому моменту вам будет вполне комфортно изучать документацию самого Gradle, а не статьи для новичков:)
150 |
151 | ### Maven Wrapper
152 |
153 | В данном пункте мы не будем в полном смысле слова знакомиться с Maven Wrapper, лишь отметим несколько ключевых
154 | моментов:
155 |
156 | 1. Концепция Maven Wrapper полностью аналогична концепции Gradle Wrapper;
157 | 2. Maven куда более стабилен от версии к версии, чем Gradle, что делает Wrapper для него менее актуальным. Но даже
158 | он со временем обрастает изменениями и новшествами, что и стало причиной появления Wrapper'а;
159 | 3. Как и в случае с Gradle, синтаксис работы с консольным интерфейсом через `mvn` и `mvnw`/`mvnw.cmd` (скрипты для
160 | работы с Maven Wrapper) отличается лишь обращением к самой команде, в остальном оставаясь идентичным;
161 | 4. Документацию и базовые инструкции по работе с Maven Wrapper можно найти по ссылке:
162 | [Maven Wrapper](https://maven.apache.org/wrapper/).
163 |
164 | ## Что дальше?
165 |
166 | На самом деле, при похожей структуре статей по Maven и Gradle, на данный момент можно сказать, что с Maven мы
167 | познакомились в большем объеме. Во многом это связано с многообразием возможностей и синтаксиса, предоставляемого
168 | Gradle - из-за этого тяжело давать информацию, которая будет объяснять принципы работы различных механизмов в Gradle
169 | на концептуальном уровне, при этом давать синтаксис и какую-то полезную в практических задачах информацию. Чтобы
170 | разобрать это действительно качественно, пришлось бы каждую тему разбивать на три статьи: "Принципы работы",
171 | "синтаксис" и "практика использования". В этом плане Maven сильно проще за счет однообразия синтаксиса - все три
172 | пункта можно объяснять на одних и тех же примерах.
173 |
174 | Из описанного выше и следуют рекомендации по дальнейшему изучению:
175 |
176 | 1. **Объекты Gradle**. Стоит разобраться с зонами ответственности Project, Settings, Configuration и прочими - хотя
177 | бы на интерфейсном уровне. Именно в этом лежит ключ к пониманию, как работает и какими понятиями оперирует Gradle;
178 | 2. **Groovy и/или Kotlin DSL**. Как и любой DSL, языки конфигурации в Gradle весьма гибкие в контексте своих задач и
179 | относительно легко расширяемы - в т.ч. посредством DSL-плагинов. Стоит осознать, что файлы конфигурации - по сути,
180 | просто скрипты, практически программный код, который можно писать в относительно свободной форме. Именно
181 | знание (или хотя бы хорошее понимание) синтаксиса лежит в основе комфортной работы с Gradle. Без этого иногда
182 | становится проблемой даже поддержка планов сборки даже существующего проекта, не требующего частых правок;
183 | 3. **Знакомство с ключевыми плагинами**. Сюда можно отнести как Core-плагины - вроде `java` и `java-library`, так и
184 | наиболее популярные в современной Java-разработке сторонние плагины - например, плагины для работы со Spring Boot.
185 | Но, полагаю, до получения коммерческого опыта лучше ограничиться Core-плагинами, остальными лишь использовать по
186 | мере необходимости - иначе есть шанс начать изучать не то что нужно, или не с теми акцентами, которые необходимы
187 | в прикладных задачах;
188 | 4. **Написание собственных тасок и/или плагинов**. Если опыт написания плагинов нужен не слишком часто, то собственные
189 | задачи на Groovy/Kotlin DSL стоит попытаться писать - хотя бы для знакомства с синтаксисом и возможности понять,
190 | что за самопальные таски вы видите в проекте на своем первом месте работы:)
191 | 5. **Работа с зависимостям**и. Мы познакомились с базовым синтаксисом, но огромное количество инструментов осталось за
192 | пределами курса. И именно эти инструменты, вероятно, еще не раз послужат поводом для удивления, когда система
193 | сборки будет вести себя не так, как вы ожидали;
194 | 6. **Работа с многопроектными сборками**. Как и в Maven, этот пункт не слишком сложен на практике, но требует время для
195 | того, чтобы с ним разобраться. И это может стать хорошей точкой входа для знакомства с плагином `java-library`.
196 |
197 | К сожалению, изучение систем сборки за пределами реальных проектов - трудоемкое и не слишком эффективное занятие.
198 | Плохая новость заключается в том, что в рамках коммерческой разработки редко приходиться работать с системами сборки
199 | в рамках конкретных задач, что приводит к достаточно слабому уровню владения системами сборки у разработчиков и, как
200 | следствие, ступору и ошибкам, когда таки приходится коснуться конфигурации Gradle за пределами базовых операций по
201 | работе с зависимостями.
202 |
203 | Но, как и всегда, дорогу осилит идущий. И понимая потенциальные узкие места в профессиональном развитии,
204 | прорабатывать их гораздо проще:)
205 |
206 | #### На сегодня все!
207 |
208 | 
209 |
210 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
211 | >
212 | > Канал: https://t.me/ViamSupervadetVadens
213 | >
214 | > Мой тг: https://t.me/ironicMotherfucker
215 | >
216 | > **Дорогу осилит идущий!**
217 |
--------------------------------------------------------------------------------
/lessons/web-and-java-ee/135/Web. Java EE. Intruduction.md:
--------------------------------------------------------------------------------
1 | # Web и Java EE. Введение
2 |
3 | Сегодня мы начинаем первый из разделов, связанных с разработкой Back-end приложений на Java - именно на обучение
4 | этому и направлен этот курс в первую очередь.
5 |
6 | Данная статья - обзорная, направленная на общее описание того, что будет в ближайших уроках. Вероятно, этот раздел
7 | станет одним из сложнейших во всем курсе - необходимо как разобраться с основными концепциями и механизмами, на которых
8 | базируется коммуникация по Сети, так познакомиться с инструментами в Java, позволяющими использовать данные механизмы.
9 |
10 | Основная проблема обозначенного раздела в том, что многообразие тем, которые можно затронуть, огромно. И каждую из
11 | них можно рассматривать на различных уровнях погружения. Поэтому будем стараться выдерживать баланс между системным
12 | подходом и целесообразностью изучения тех или иных подразделов для начинающих специалистов.
13 |
14 | По озвученной выше причине текущий раздел будет содержать достаточно много статей без практики или с практикой, не
15 | касающейся непосредственно программирования. Главной задачей раздела станет формирование базового представления о
16 | работе веб-приложений, в том числе с использованием Java.
17 |
18 | Именно сегодня мы разберем ряд важных понятий, без которых будет невозможным дальнейшее знакомство с
19 | разделом.
20 |
21 | ## Web
22 |
23 | Для начала стоит определиться с терминологией. Скорее всего, вы знакомы с этими терминами в той или иной степени, но
24 | я считаю нужным их проговорить явно для исключения недопонимания.
25 |
26 | Под **web** (веб) обычно понимают **World Wide Web**, он же **Интернет**.
27 |
28 | **Веб-ресурс** - любой ресурс, доступный посредством сети - будь то локальная сеть, либо Интернет. Это могут быть
29 | веб-страницы, мультимедиа (видео, аудио и пр.), документы в различных форматах и т.д. Как правило, обычный пользователь
30 | получает доступ к веб-ресурсам через браузер.
31 |
32 | **Веб-страница** - HTML-документ, который содержит текст, медиа, ссылки на другие веб-ресурсы или иной контент. В
33 | узком смысле, почти все, что вы видите в окне браузера - веб-страницы.
34 |
35 | **Веб-сайт** (или просто **сайт**) - вид комплексного веб-ресурса, который обычно состоит из одной или нескольких
36 | веб-страниц. Как правило, эти страницы имеют статическое содержимое и не содержат сложной логики. Основное их
37 | назначение - предоставление какой-либо информации в текстовом или медиа формате. Наиболее простые примеры - различные
38 | лендинги.
39 |
40 | **Веб-приложение** - еще один "комплексный" веб-ресурс, который предоставляет большую интерактивность, чем
41 | веб-сайт. Функциональность такого приложения может быть различна по направленности и интерактивности взаимодействия.
42 | К веб-приложениям можно отнести социальные сети, браузерные игры и множество других b2b (business-to-business) и b2c
43 | (business-to-consumer) продуктов. В современном мире достаточно тяжело выделить чистые веб-сайты, в силу того, что
44 | многие продукты, даже информационной направленности имеют те или иные интерактивные функции.
45 |
46 | В более узком смысле, веб-приложением можно назвать и приложения с мобильным или десктопным клиентом, работающими с
47 | сетью. Но это частности, которые сейчас не имеют особого значения.
48 |
49 | В целом, сам термин "веб-приложение" достаточно популярен и интуитивно понятен. Нас же больше будут интересовать
50 | следующие аспекты:
51 |
52 | 1. Из каких компонентов состоит веб-приложение;
53 | 2. Как конечный пользователь взаимодействует с веб-приложением;
54 | 3. Как компоненты веб-приложения передают информацию между собой.
55 |
56 | ### Клиент-серверная архитектура
57 |
58 | В абсолютном большинстве случаев веб-приложение строится на базе архитектуры **клиент-сервер**.
59 |
60 | Эта архитектура подразумевает наличие двух компонентов системы: **клиента** и **сервера**.
61 |
62 | Определить каждый из компонентов на бытовом уровне достаточно легко, но при построении всеобъемлющей теоретической
63 | модели могут возникнуть сложности*. К счастью, нас интересует базовое понимание этих терминов.
64 |
65 | Клиентом в этой модели является тот, что запрашивает какую-либо информацию или запрашивает выполнения каких-либо
66 | действий. В простейшем представлении для веб-сайта или веб-приложения клиентом выступает браузер. Именно он будет
67 | запрашивать у сервера веб-страницы, файлы или что-то еще. Также он, как клиент, может отправить информацию или файл
68 | на сервер и "запросить" произвести какие-либо действия с этими данными - сохранить или обработать каким-либо образом.
69 |
70 | Сервером же выступает некий вычислительный узел, который предоставляет клиентам данные (веб-страницы, файлы и т.д.)
71 | или услуги (сохранение поступивших данных, их обработка и пр.). При этом в упрощенной модели один клиент в момент
72 | времени работает лишь с одним сервером, а сервер может обрабатывать запросы от множества клиентов одновременно.
73 |
74 | > *Реальная жизнь несколько сложнее и роли в ней запутаннее. Так, клиентом для одного сервера может выступать другой
75 | > сервер. А может быть просто коммуникация между серверами, при этом эта коммуникация все еще может рассматриваться
76 | > в концепции "клиент-сервер".
77 | >
78 | > Так и клиент может взаимодействовать с несколькими физическими серверами одновременно, даже в рамках одного
79 | > веб-приложения.
80 | >
81 | > Но эти нюансы не влияют на восприятие базовой концепции, лишь являются удобной проекцией при разработке того или
82 | > иного компонента системы.
83 |
84 | Технически, и клиент, и сервер могут располагаться на одном компьютере. С этим мы еще столкнемся при запуске
85 | собственных веб-приложений.
86 |
87 | В пределах этого курса мы будем сконцентрированы на разработке именно серверной части веб-приложений - именно она
88 | называется backend'ом.
89 |
90 | ### Сетевое взаимодействие
91 |
92 | Для обеспечения связи между серверами и сервером и клиентом в Сети используются различные стандартизированные
93 | механизмы передачи данных - **протоколы передачи данных**.
94 |
95 | Это отдельная объемная тема, в которой можно рассказать о различных протоколах, их видах и классификациях.
96 |
97 | В текущем разделе мы будем знакомиться с наиболее популярным способом коммуникации для веб-приложений - протоколом HTTP.
98 |
99 | И именно он будет основным (или единственным) способом сетевой коммуникации, который мы будем использовать в рамках
100 | курса. Он позволяет передавать как текстовую информацию (в т.ч. HTML-документы), так и медиа или иные файлы.
101 |
102 | Также на базе этого протокола строятся некоторые более высокоуровневые логические концепции, которые мы тоже
103 | затронем в свое время. В первую очередь - [REST](https://ru.wikipedia.org/wiki/REST).
104 |
105 | ## Java EE
106 |
107 | **Java EE** - **Java Enterprise Edition** - он же **Jakarta EE** и еще несколько названий и аббревиатур, актуальных
108 | в те или иные промежутки времени. Это общее название для совокупности спецификаций, разработанных для проектирования
109 | архитектуры серверных компонентов веб-приложений. Данные спецификации предназначены для различных задач, от коммуникации
110 | по сети до внутренней организации кода приложения, взаимодействия с РСУБД и даже клиентской части веб-приложения.
111 |
112 | В данном случае, каждую спецификацию можно понимать как отдельную Java-библиотеку, содержащую ряд интерфейсов и
113 | аннотаций, обычно без реализации для них. У спецификации может быть множество реализаций, отличающихся внутренним
114 | устройством и дополнительными возможностями. Ниже мы рассмотрим примеры отдельных спецификаций, входящих в Java EE.
115 | Но в комплексе описанная ситуация иногда вызывает путаницу у новичков.
116 |
117 | Важно понимать, что технологии развиваются, какие-то вещи остаются актуальными, а какие-то - уходят в прошлое.
118 | Поэтому какие-то компоненты Java EE используются и сейчас, другие можно встретить лишь на старых проектах, третьи -
119 | нашли свое продолжение в библиотеках и фреймворках, которые давно переросли возможности, заложенные в спецификацию,
120 | хоть формально и являются ее реализацией.
121 |
122 | При этом сам проект Java EE продолжает развиваться под брендом Jakarta EE. Полный список предоставляемых
123 | спецификаций можно найти здесь: [ссылка](https://jakarta.ee/specifications/). Там же можно найти документацию по
124 | каждой из них.
125 |
126 | Общей чертой спецификаций из Java EE можно считать то, что их код - интерфейсы, классы и аннотации хранится в
127 | пакетах с префиксом `javax` или `jakarta` - в зависимости от версии спецификации.
128 |
129 | > *Различие в пакетах связано с вопросом авторских прав и практического интереса не предоставляет. Поэтому особо
130 | > углубляться в эту тему не будем.
131 |
132 | Ниже приведены некоторые спецификации с короткими пояснениями.
133 |
134 | ### Servlet API
135 |
136 | Спецификация, на базе которой в Java строится классический подход для работы с HTTP со стороны сервера. Знакомству с
137 | Servlet API будет посвящен ряд статей в данном разделе.
138 |
139 | ### Java Persistence API (JPA)
140 |
141 | Спецификация для работы с РСУБД на большем уровне абстракции, чем в JDBC. С этой спецификацией и ее наиболее
142 | популярной реализацией мы будем знакомиться в разделе "JPA и Hibernate".
143 |
144 | ### JavaServer Pages (JSP) и JavaServer Pages Standard Tag Library (JSTL)
145 |
146 | JSP - спецификация, позволяющая формировать веб-страницы стороне сервера и передавать их клиенту с использованием
147 | Servlet API.
148 |
149 | JSTL - более продвинутая спецификация, расширяющая возможности JSP, в т.ч. обеспечивающие большую динамичность
150 | формируемых веб-страниц.
151 |
152 | Эти спецификации утратили свою популярность с развитием технологий для Front-end разработки и теперь почти не
153 | используются. Но мы тезисно ознакомимся с их возможностями в одной из статей этого раздела.
154 |
155 | ### Java Message Service (JMS)
156 |
157 | Спецификация, обеспечивающая один из подходов по обмену сообщениями между различными серверами. Скорее всего, мы не
158 | будем затрагивать ни эту спецификацию, ни технологии, ее поддерживающие, в рамках курса. Но шанс столкнуться на
159 | практике с JMS или ее "наследниками" - крайне высокий.
160 |
161 | Хорошая новость заключается в том, что от начинающих специалистов знакомства с этими технологиями обычно не требуют.
162 |
163 | > По сути, JMS обеспечивает взаимодействие Java с брокерами сообщений. Это может быть точкой входа, если вам
164 | > захочется нырнуть в эту тему самостоятельно.
165 |
166 | ### Bean Validation API
167 |
168 | Относительно небольшая спецификация для валидации сущностей. Мы не будем рассматривать ее отдельно, но немного
169 | затронем предоставляемые возможности при знакомстве с Spring.
170 |
171 | ### Java API for XML Web Services (JAX-WS)
172 |
173 | Спецификация, обеспечивающая коммуникацию с использованием протокола [SOAP](https://ru.wikipedia.org/wiki/SOAP).
174 | Не будет рассматриваться в рамках курса, но на практике есть шанс столкнуться с ней, особенно на старых проектах.
175 |
176 | Хорошая новость в том, что на собеседованиях о ней спрашивают редко, особенно junior-специалистов.
177 |
178 | ### Java API for RESTful Web Services (JAX-RS)
179 |
180 | Спецификация для работы с HTTP с использованием архитектурного подхода REST.
181 |
182 | Является относительно непопулярной, в силу того, что Spring ее не использует в базовой реализации. Но при этом может
183 | использоваться в проектах, которые не используют сам Spring.
184 |
185 | В курсе мы познакомимся с REST, но не будем касаться самой спецификации.
186 |
187 | ## Заключение
188 |
189 | Как было сказано в начале статьи, раздел крайне объемный и охватить его целиком в курсе для новичков практически
190 | невозможно. Поэтому в следующих статьях постараемся сконцентрироваться на наиболее критичных направлениях,
191 | постепенно формируя фундамент, который в дальнейшем позволит изучать нужные подходы, спецификации и библиотеки
192 | самостоятельно, встраивая их в единую систему представлений о Back-end разработке.
193 |
194 | #### На сегодня все!
195 |
196 | 
197 |
198 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
199 | >
200 | > Канал: https://t.me/ViamSupervadetVadens
201 | >
202 | > Мой тг: https://t.me/ironicMotherfucker
203 | >
204 | > **Дорогу осилит идущий!**
205 |
--------------------------------------------------------------------------------
/lessons/java-core/013/Inheritance. Keywords extends and super. Access modifier protected.md:
--------------------------------------------------------------------------------
1 | # Наследование. Ключевое слово extends и использование protected. Ключевое слово super. Приведение ссылочных типов
2 |
3 | ## Понятие наследования
4 |
5 | Сегодня мы познакомимся со следующим принципом ООП, который позволит нам более гибко работать с классами и обобщать их
6 | при необходимости.
7 |
8 | **Наследование** – принцип ООП, который заключается в возможности «наследовать» данные (поля) или логику (методы)
9 | другого типа данных. Эта функциональность сильно упрощает переиспользование общей кодовой базы у классов, которые имеют
10 | схожее назначение.
11 |
12 | Предлагаю ознакомиться со [статьей](https://metanit.com/java/tutorial/3.5.php).
13 |
14 | Также можно ознакомиться с видео:
15 | [](https://www.youtube.com/watch?v=IkhLWR_l-gM)
16 |
17 | Теперь разберемся немного подробнее.
18 |
19 | ## Extends. Модификатор доступа protected
20 |
21 | С синтаксисом `extends` вы уже познакомились в рамках статьи на metanit. Теперь поговорим об ограничениях наследования
22 | и особенностях доступа к данным **суперкласса**. Какие-то из них были отражены в статье, какие-то – нет:
23 |
24 | - У класса может быть не более одного **предка** (суперкласса). Таким образом Java избегает
25 | [проблему ромба](https://ru.wikipedia.org/wiki/Ромбовидное_наследование), возникающую при множественном наследовании.
26 | Она все равно возможна, но об этом мы поговорим в дальнейших статьях;
27 | - Мы можем ограничить возможность наследоваться от нашего класса. Если знакомое нам ключевое слово `final` указать
28 | перед классом (например, `public final class`), это покажет Java, что данный класс – **финализирован**,
29 | наследование от него недопустимо. Например, знакомый нам класс `String` помечен как `final`;
30 | - Все классы в Java так или иначе наследуются от базового класса `Object`. Его мы будем подробно разбирать в следующих
31 | уроках. На данном этапе стоит запомнить, что даже если при объявлении класса не указан `extends` – класс все равно
32 | имеет предка в лице `Object`. Например, метод, который мы использовали для сравнения строк – `equals()` – присутствует
33 | во всех классах, потому что является одним из 9 методов класса `Object`;
34 | - Если класс имеет явно указанного предка – он наследует `Object` посредством суперкласса. Иерархия наследования будет
35 | выглядеть как `Object` – `Superclass` – `Subclass`;
36 | - Глубина наследования в Java не ограничена. Но на практике, если не говорить о каких-либо библиотеках, редко достигает
37 | больше 4 уровней, считая наследование от `Object`;
38 | - Количество возможных наследников для определенного класса – также не ограничено;
39 | - Мы можем получить доступ к полям, методам и конструкторам суперкласса. Но только к тем, которые помечены
40 | модификаторами `public` или `protected`. А также `package-private` (модификатор по умолчанию), но только при условии,
41 | что наследник находится в том же пакете, что и предок.
42 |
43 | Касаясь использования модификаторов доступа в наследовании, стоит также отметить, что те поля и методы, которые
44 | предполагаются только для использования в класса-наследниках, обычно помечаются как `protected`. Использовать геттеры и
45 | сеттеры для работы с полями суперкласса не принято. Исключения, как всегда, зависят от нюансов конкретной задачи.
46 |
47 | Наследование и связанная с ним функциональность имеет и другие подводные камни, с которыми мы будем знакомиться по мере
48 | углубления в Java-разработку.
49 |
50 | ## Ключевое слово super
51 |
52 | С самим синтаксисом `super` и вариантами использования мы уже знакомы. Подчеркнем некоторые моменты:
53 |
54 | - Ключевое слово `super` похоже на `this`, но позволяет обращаться к конструкторам, методам (или их реализациям в
55 | суперклассе, познакомимся с этим в ближайших уроках) и полям суперкласса (на самом деле, использовать `super` для
56 | доступа к полю – избыточно);
57 | - Нет, `super.super` – не сработает:);
58 | - `super` не отменяет ограничений по модификаторам доступа, описанных в предыдущем подразделе. Получить доступ к
59 | private-методу суперкласса не получится;
60 | - Любой конструктор неявно вызывает `super()` – конструктор суперкласса по умолчанию – первой строчкой, если не указан
61 | вызов другого конструктора текущего класса через `this()`;
62 | - Если мы хотим вызвать в конструкторе **класса-потомка** другой конструктор суперкласса (не по умолчанию) – мы должны
63 | передать в `super()` параметры, подходящие нужному нам конструктору;
64 | - Если конструктор по умолчанию отсутствует в суперклассе – мы обязаны явно вызвать `super()` с параметрами. Иначе
65 | произойдет ошибка компиляции;
66 | - Вызов `this()` или `super()` – всегда должен идти первой строчкой, это ограничение Java. Соответственно, вызвать явно
67 | и то, и другое не получится.
68 |
69 | Стоит отметить, что в промышленной разработке явный вызов `super` – не слишком распространенная практика. Особенно за
70 | пределами вызова конструктора суперкласса. Ничего плохого в его использовании нет, но и необходимость в нем возникает
71 | очень редко.
72 |
73 | ## Приведение ссылочных типов
74 |
75 | Теперь немного затронем тему переменных ссылочных типов. Мы уже работали с ними, как используя объекты класса `String`,
76 | так и для работы с объектами наших собственных классов. Но в контексте наследования мы имеем несколько важных
77 | особенностей.
78 |
79 | Рассмотрим пример. Пусть у нас есть класс `SuperClass` и его наследник - `SubClass`:
80 |
81 | ```java
82 | public class SuperClass {
83 | public void doSth() {
84 | //sth logic
85 | }
86 | }
87 |
88 | public class SubClass extends SuperClass {
89 | public void doSth2() {
90 | //sth logic
91 | }
92 | }
93 | ```
94 |
95 | Мы можем создать объект класса `SubClass`, присвоить переменной типа `SubClass` и использовать методы как наследника,
96 | так и предка:
97 |
98 | ```java
99 | SubClass subClass = new SubClass();
100 | subClass.doSth(); // OK
101 | subClass.doSth2(); // OK
102 | ```
103 |
104 | В целом, это логично и достаточно очевидно.
105 |
106 | Но также мы можем объект класса `SubClass` присвоить переменной типа `SuperClass`. Но тогда мы можем использовать только
107 | ту функциональность, которая будет доступна для объектов `SuperClass`:
108 |
109 | ```java
110 | SuperClass subClass = new SubClass();
111 | subClass.doSth(); // OK
112 | subClass.doSth2(); // Oшибка компиляциии
113 | ```
114 |
115 | При таком подходе у нас произойдет **расширяющее приведение**. Оно также называется **повышающим** или **неявным**
116 | (поскольку не требует явного указания о касте). Проводя аналогии с примитивными типами, похожую ситуацию мы можем
117 | наблюдать при касте `int` к `long`. Также такое приведение называют **upcasting**.
118 |
119 | Тот же механизм применим к полям и параметрам методов: в поле или параметр типа `SuperClass` мы всегда можем передать
120 | объект типа `SubClass`.
121 |
122 | Расширяющим такое приведение называется, потому что суперкласс – более обширная по значению сущность, нежели его
123 | наследник. Примером в реальной жизни может быть отношение между классом `Животное` (суперкласс) и классом `Собака`
124 | (класс-наследник). Животное – явно более общая (широкая) сущность, нежели собака. И очевидно, что каждая собака
125 | является животным.
126 |
127 | > Интересный факт: в переменную типа `Object` мы можем записать объект вообще любого типа. Потому что `Object` – предок
128 | > всех остальных классов.
129 |
130 | Однако зачем такой механизм нужен в Java, если он ограничивает функциональность объекта?
131 |
132 | Как правило, она используется для случаев, когда мы либо не знаем заранее, какой из классов-наследников (либо это
133 | действительно объект суперкласса) будет использоваться (например, будет передан в наш метод в качестве параметра), либо
134 | нам не важен реальный тип (массив животных, куда могут быть переданы и элементы-собаки, и элементы-коты).
135 |
136 | Подобная механика также позволяет реализовывать многие принципы **объектно-ориентированного дизайна**
137 | (некоторые из [SOLID](https://ru.wikipedia.org/wiki/SOLID_(программирование)), например), но с ними мы познакомимся
138 | намного позже.
139 |
140 | Существует и обратная механика – **сужающее (явное, понижающее) приведение**. Оно же **downcasting**. Аналогия с
141 | примитивами – приведение `long` к `int`.
142 |
143 | Используя классы из прошлого примера, можно сделать так:
144 |
145 | ```java
146 | SuperClass subClass = new SubClass();
147 | SubClass castedSubClass = (SubClass) subClass;
148 |
149 | subClass.doSth(); // OK
150 | subClass.doSth2(); // OK
151 | ```
152 |
153 | В нашем примере мы точно уверены, что переменная `subClass` ссылается на объект типа `SubClass`. К сожалению, эта
154 | уверенность есть не всегда. Поэтому мы имеем риск получить **ошибку приведения**, если окажется, что
155 | переменная `subClass` ссылается на объект типа `SuperClass` или на другого его наследника.
156 |
157 | Область применения данной механики намного уже, чем у расширяющего приведения. В большинстве случаев она сводится к
158 | тому, что некая обобщенная логика вернула нам объект типа `SubClass` в переменной типа `SuperClass`, но в рамках уже
159 | нашей логики (метода или какого-то блока кода внутри метода) нам необходима функциональность, доступная только в
160 | классе-наследнике. В таком случае, сужающее приведение имеет смысл.
161 |
162 | Само собой, существуют способы убедиться, что к нам пришел объект нужного типа и мы можем его безбоязненно кастить.
163 | Однако с ними мы познакомимся лишь через несколько уроков.
164 |
165 | Наследование – достаточно глубокая тема. К сожалению, чаще всего практика применения наследования идет рука об руку с
166 | третьим принципом ООП – **полиморфизмом**. С ним мы познакомимся в следующем уроке. И именно тогда сможем в
167 | полной мере оценить прелесть самого наследования.
168 |
169 | #### С теорией на сегодня все!
170 |
171 | 
172 |
173 | Переходим к практике:
174 |
175 | ## Задача 1:
176 |
177 | Реализовать класс `Animal`, содержащий protected-конструктор без параметров, который выводит в консоль сообщение `I’m
178 | an animal`.
179 |
180 | Реализовать для `Animal` классы-наследники `Dog` и `Cat`. Реализовать для каждого из них приватный конструктор без
181 | параметров, который выводит в консоль сообщение `I’m a dog` (`I’m a cat`). Также реализовать публичный конструктор,
182 | принимающий строковый параметр `color`. Он должен вызывать конструктор без параметров, а также выводить в консоль
183 | сообщение `I’m a dog` (`I’m a cat`), где `color` – значение параметра конструктора `color`.
184 |
185 | Создайте в `main()` экземпляр `Dog` и экземпляр `Cat`. Обратите внимание на консоль. Такой ли порядок сообщений вы
186 | ожидали увидеть?
187 |
188 | ## Задача 2 (*):
189 |
190 | Реализуйте класс `Animal`. Реализуйте его наследников: `Dog`, `Cat`, `Cow`. Каждый из наследников должен содержать свой
191 | метод: `woof()`, `meow()` и `moo()` соответственно. Остальные поля и методы суперкласса и наследников реализовать по
192 | своему усмотрению, если они необходимы.
193 |
194 | Каждый из методов должен выводить в консоль соответствующую ему строку: `woof`, `meow` или `moo`.
195 |
196 | В `main()` создать и наполнить в произвольном порядке объектами разных классов-наследников массив типа `Animal`.
197 | Реализовать метод, принимающий массив `Animal` и вызывающий метод, характерный для конкретного животного.
198 |
199 | Использовать при решении `instanceof`, `getClass()` или другие еще неизвестные нам механики – недопустимо.
200 |
201 | Дополнительное условие (необязательно): решить задачу, при условии, что `woof()`, `meow()` и `moo()` внутри себя
202 | выполняют только вызов protected-метода `sound()`, который определен в `Animal`.
203 |
204 | > Примечание: не забывайте об использовании пакетов. Название продуктов (пакет 3-го уровня) для задач текущего урока
205 | > предлагаю выбрать самостоятельно.
206 |
207 | **Разбор практики для этого урока**:
208 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson13_inheritance)
209 |
210 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
211 | >
212 | > Канал: https://t.me/ViamSupervadetVadens
213 | >
214 | > Мой тг: https://t.me/ironicMotherfucker
215 | >
216 | > **Дорогу осилит идущий!**
217 |
--------------------------------------------------------------------------------
/lessons/java-core/010/Fields. Keyword static. Constants.md:
--------------------------------------------------------------------------------
1 | # Поля класса. Ключевое слово static. Константы
2 |
3 | ## Поля класса
4 |
5 | Мы уже познакомились с таким синтаксисом как поле. Оно позволяет хранить определенную информацию внутри объекта,
6 | являясь, по сути, переменной уровня класса. Сегодня мы более подробно разберемся с особенностями этого синтаксиса.
7 |
8 | Первое, что хотелось бы отметить – **дефолтные** (по умолчанию) значения полей. Если обычные переменные мы обязаны
9 | инициализировать явно (некоторые из вас уже столкнулись с ошибкой компиляции, если этого не сделать), то с полями
10 | класса все иначе.
11 |
12 | Если мы создали поле класса и ни на каком этапе не задаем значение этого поля, Java не увидит в этом ошибки. По той
13 | простой причине, что она неявно дала значение каждому полю сразу при его объявлении, в зависимости от его типа:
14 |
15 | - `byte`, `short`, `int`, `long` – инициализируются значением `0`;
16 | - `char` – инициализируется символом, код которого – `0`. Данный символ нечитаем, но он есть. Вы можете прочесть
17 | больше, загуглив _«\u0000»_;
18 | - `double`, `float` – значением по умолчанию будет `0.0`;
19 | - `boolean` – будет инициализирован значение `false`;
20 | - Абсолютно все ссылочные типы, включая хорошо известный нам `String` – инициализируются значением `null`.
21 |
22 | Если с примитивами все просто, то с `null` мы ранее не сталкивались. Это ключевое слово, которое означает, что
23 | переменная ссылочного типа не содержит никакой ссылки на объект. Соответственно, обращение к полям и методам такой
24 | переменной завершится с ошибкой (исключением). Поэтому при работе с ссылочными типами достаточно часто используется
25 | проверка на `null` вида `object != null`.
26 |
27 | Также стоит рассмотреть способы инициализации полей класса. Мы уже знакомы с инициализацией с помощью конструктора,
28 | также в статье на [metanit](https://metanit.com/java/tutorial/3.1.php) было упоминание о блоках инициализации (они нас
29 | все еще не интересуют, поскольку данная функциональность практически не используется).
30 |
31 | Кроме этого, инициализацию полей мы можем производить в методах класса, если того требует логика нашего класса или
32 | приложения. Первичная инициализация в методе – достаточно узкий случай, а вот изменять значения в методе мы даже
33 | попробовали самостоятельно в практическом задании прошлого урока.
34 |
35 | И последним, хоть и самым очевидным, способом первичной инициализации является инициализация при объявлении. Ровно
36 | также, как мы часто делаем с переменными. Инициализировать таким образом мы можем поля и примитивных, и ссылочных типов:
37 |
38 | ```java
39 | public class Car {
40 | public int maxSpeed = 240;
41 | public String color = "Красный";
42 | public Counter mileage = new Counter("Пробег");
43 | }
44 | ```
45 |
46 | Кроме того, мы можем использовать одни поля класса при инициализации других. Главное, чтобы инициализируемое поле было
47 | расположено ниже тех, которые используются для инициализации:
48 |
49 | ```java
50 | public class FullName {
51 | public String firstName = "Иван";
52 | public String lastName;
53 | public String fullName = firstName + " " + lastName;
54 | }
55 | ```
56 |
57 | При этом нет разницы, инициализированы использованные поля явно или нет. В нашем примере поле `fullName` будет
58 | инициализировано значением "Иван null".
59 |
60 | В любом случае, я не советую использовать инициализацию поля при объявлении, по крайней мере, на данном этапе. Зачастую
61 | такая логика приводит к излишней запутанности и неожиданным **багам**. Исключением являются **константы**, но об этом
62 | ниже.
63 |
64 | ## Ключевое слово static
65 |
66 | Мы уже встречались со `static` ранее, при знакомстве с методами, но использовали его без понимания того, что он
67 | делает и для чего нужен.
68 |
69 | Данное ключевое слово можно применить к полю и методу (еще к **вложенному классу**, но не трогайте, это на Новый Год).
70 |
71 | В обоих случаях данное ключевое слово будет означать, что поле (или метод) относится не к объекту класса, а
72 | непосредственно к классу. Т.е. нам не нужно создавать объект, чтобы использовать данное поле (или метод).
73 |
74 | Ярким примером static-поля может быть поле `out` класса `System`: `System.out` – мы обращаемся к нему, не создавая
75 | объект класса `System`. Общий синтаксис обращения к статическому полю:
76 |
77 | ```
78 | имя_класса.имя_поля
79 | ```
80 |
81 | Наиболее распространенное применение статических полей – константы. В следующем пункте мы разберем их подробнее.
82 |
83 | Статические методы, в свою очередь, хорошо демонстрирует уже известный нам класс `Math`. Например: `Math.pow(2, 3)`.
84 | Здесь мы вызываем метод, не создавая объект класса `Math`. Общий синтаксис:
85 |
86 | ```
87 | имя_класса.имя_поля([аргументы метода])
88 | ```
89 |
90 | Наиболее распространенное (и, практически, единственное) применение static-методов – утилитарные методы, в которых
91 | объект не нужен. Например, математические операции, простейшие конвертеры и пр.
92 |
93 | На самом деле, тема использования static-методов намного глубже, чем кажется на первый взгляд и допустимость их
94 | использования тесно связано как с концепцией ООП, так и с особенностями реализации этой концепции в Java. Поэтому если с
95 | static-полями мы почти полностью разберемся уже сегодня, то к static-методам еще будем возвращаться несколько раз.
96 |
97 | Немного о нюансах использования. С методами это не так критично (разберем чуть ниже), но с полями неграмотное
98 | использование `static` может сыграть злую шутку. Рассмотрим на примере:
99 |
100 | ```java
101 | public class Counter {
102 | public static int counter;
103 | }
104 |
105 | public static void main(String... args) {
106 | Counter counter1 = new Counter();
107 | Counter counter2 = new Counter();
108 |
109 | counter1.counter++;
110 | counter2.counter++;
111 |
112 | System.out.println(counter1.counter + " " + counter2.counter);
113 | }
114 | ```
115 |
116 | Вывод в консоль:
117 |
118 | ```
119 | 2 2
120 | ```
121 |
122 | Поскольку static-поля относятся именно к классу, а не объекту, значение такого поля будет общим на весь класс. По
123 | сути, код выше равноценен следующему:
124 |
125 | ```java
126 | public class Counter {
127 | public static int counter;
128 | }
129 |
130 | public static void main(String... args) {
131 | Сounter.counter++;
132 | Сounter.counter++;
133 |
134 | System.out.println(Сounter.counter + " " + Сounter.counter);
135 | }
136 | ```
137 |
138 | Использование static-методов имеет свои ограничения: мы не можем внутри статического метода обратиться к не
139 | статическому полю/методу, не создав экземпляр класса (использовать `this` – тоже не можем). Т.е:
140 |
141 | ```java
142 | public class SthClass {
143 |
144 | public static void doSth() {
145 | doSth1();
146 | }
147 |
148 | public void doSth1() {
149 | // Какая-то логика
150 | }
151 | }
152 | ```
153 |
154 | Приведет к ошибке компиляции. Чтобы подобный код заработал, нужно сделать следующее:
155 |
156 | ```java
157 | public class SthClass {
158 |
159 | public static void doSth() {
160 | SthClass sthObject = new SthClass();
161 | sthObject.doSth1();
162 | }
163 |
164 | public void doSth1() {
165 | // Какая-то логика
166 | }
167 | }
168 | ```
169 |
170 | К слову, именно поэтому при первом знакомстве с методами я рекомендовал помечать их как `static` – чтобы мы могли их
171 | использовать в статическом методе `main()` до того, как изучим конструкторы.
172 |
173 | Однако если вы в рамках статического метода создаете объект того же класса – почти гарантированно вы где-то свернули не
174 | туда. Исключения есть, но к моменту, когда они вас коснутся, использование `static` вряд ли будет вызывать у вас
175 | какие-либо вопросы.
176 |
177 | ## Константы
178 |
179 | Мы уже знакомы с тем, как объявить переменную-константу внутри метода. Константы уровня класса достаточно похожи, для
180 | их объявления также используется ключевое слово `final`. Но есть и отличия.
181 |
182 | Первое из них заключается в том, что инициализировать константное поле мы можем не только при объявлении, но также и в
183 | конструкторе, и в блоке инициализации. Но для одной константы может быть использован только один способ инициализации.
184 | Не инициализировать константу вовсе – нельзя, это будет ошибкой компиляции.
185 |
186 | Однако под константными полями обычно подразумеваются не просто final-поля (в каком-то смысле, их можно назвать
187 | константами уровня объекта и они тоже имеют право на жизнь), а поля, помеченные как `static final` – константы уровня
188 | класса.
189 |
190 | В такие поля часто выносят литералы, которые не будут изменяться в ходе программы. Это могут быть какие-то строки,
191 | особенно, если одно строковое значение используется в рамках класса (или приложения) несколько раз, числа, особенно,
192 | если это какие-либо коэффициенты для расчетов и т.д.
193 |
194 | Примером такой константы может быть
195 |
196 | ```java
197 | public static final double PI = 3.14159265358979323846;
198 | ```
199 |
200 | в классе `Math`. Обратите внимание на нейминг: константы называют прописными буквами, слова разделяются символом `'_'`.
201 | Например: `SOMETHING_CONSTANT`. Это сделано для того, чтобы отличать константные поля от обычных.
202 |
203 | Если мы вспомним [Задачу 3](https://github.com/KFalcon2022/practical-tasks/blob/master/src/lesson4_cycles/Task3.java)
204 | (рисование прямоугольника) из урока про циклы, в константы стоило бы вынести `'-'`, `'|'`, `' '`. Ведь если мы захотим
205 | нарисовать прямоугольник другими символами, заменить их будет проще в одном месте, чем искать по коду, особенно, если он
206 | разделен на методы.
207 |
208 | Обращение к константе уровня класса ничем не отличается от обращения к обычному статическому полю. Кроме того, что
209 | изменить значение такого поля мы не сможем.
210 |
211 | К слову, final-методы тоже существуют, но в них смысл слова `final` уже иной. Мы можем даже создавать
212 | final-static-методы. Другой вопрос, что такое объявление избыточно, почему – разберем в уроке, посвященном
213 | **наследованию** в Java.
214 |
215 | #### С теорией на сегодня все!
216 |
217 | 
218 |
219 | Переходим к практике:
220 |
221 | ## Задача 1:
222 |
223 | Используя кодовую базу из
224 | [задачи](https://github.com/KFalcon2022/practical-tasks/blob/master/src/com/walking/lesson6_methods/Task3.java)
225 | вынести строковые и символьные литералы в константы. Попробуйте нарисовать прямоугольник, используя `==` для каждой
226 | единицы длины и `||` – для каждой единицы ширины.
227 |
228 | Также попробуйте записать в константу переменную `scanner`. Упростится ли использование сканера внутри методов чтения с
229 | клавиатуры?
230 |
231 | ## Задача 2:
232 |
233 | Для [задачи](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson8_classes_objects)
234 | реализуйте неизменность поля названия у класса `Counter`. Ведь очень странно, если мы можем менять название счетчика по
235 | ходу выполнения программы, не так ли?
236 |
237 | ## Задача 3:
238 |
239 | Используя
240 | [задачу](https://github.com/KFalcon2022/practical-tasks/blob/master/src/com/walking/lesson7_varargs_overloading/Task5.java)
241 | (можете сделать на основе своего решения, но для наглядности удобства новых возможностей рекомендую взять за основу
242 | решение по ссылке):
243 | 1. Вынесите поиск простых чисел в отдельный класс.
244 | 2. Реализуйте возможность вывода на экран суммы N первых простых чисел, где N – число, введенное пользователем с
245 | клавиатуры;
246 | 3. Вынесите нужные вам переменные в поля класса. Если необходимо – сделайте их константами уровня класса или объекта.
247 | Помните, константа ссылочного типа гарантирует неизменность ссылки, а не содержимого объекта. Массив – ссылочный тип.
248 |
249 | Примечание: это одна задача, а не различные варианты:)
250 |
251 | **Разбор практики для этого урока**:
252 | [ссылка](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson10_static_constants)
253 |
254 | > Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
255 | >
256 | > Канал: https://t.me/ViamSupervadetVadens
257 | >
258 | > Мой тг: https://t.me/ironicMotherfucker
259 | >
260 | > **Дорогу осилит идущий!**
261 |
--------------------------------------------------------------------------------