├── 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 | 5 | 6 | 9 | 10 | 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | [![Видео](http://img.youtube.com/vi/wlKQBgJqPRs/0.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | [![Видео](http://img.youtube.com/vi/v7yZ9okDsS4/0.jpg)](https://www.youtube.com/watch?v=v7yZ9okDsS4) 14 | 15 | Видео 2 (некоторые подробности). Осторожно, есть незнакомые элементы: 16 | [![Видео](http://img.youtube.com/vi/i_IiGj65bJM/0.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](jdkStructure.png) 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 | [![ALT-УСТАНОВКА JDK](http://img.youtube.com/vi/uXMTq81jG7Y/0.jpg)](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 | [![ALT-УСТАНОВКА JDK](http://img.youtube.com/vi/JuHACj_a0Rw/0.jpg)](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 | [![ALT-УСТАНОВКА JDK](http://img.youtube.com/vi/tSTvCyqeeYY/0.jpg)](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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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://img.youtube.com/vi/ll14SKsQScE/0.jpg)](http://www.youtube.com/watch?v=ll14SKsQScE) 11 | 12 | Также рекомендую для лучшего понимания, как реализован enum в Java, посмотреть еще одно: 13 | 14 | [![Видео](http://img.youtube.com/vi/aMiemoKyiqU/0.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | [![ALT-ТИПЫ ДАННЫХ](https://img.youtube.com/vi/S1GVLezqYoE/hqdefault.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](./tomcatHomePage.png) 98 | 99 | Если это произошло - поздравляю, установка и запуск прошли успешно. 100 | 101 | Если Tomcat не был добавлен в приложения с автозапуском, вы всегда можете стартовать его вручную через 102 | соответствующий `.exe`/`.bat`/`.sh` файл - в зависимости от ОС и предпочтительного способа запуска. 103 | 104 | #### На сегодня все! 105 | 106 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](./petProject.png) 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 | [![Видео](http://img.youtube.com/vi/OE6jUYt8O4Q/0.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](./exercise4.png) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | тему: [![Видео](http://img.youtube.com/vi/SdGp-5pcPeA/0.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](./accessModifiers.png) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](javaDependencyConfigurations.png) 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 | ![img.png](javaTestDependencyConfigurations.png) 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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | ![img.png](../../../commonmedia/justTheoryFooter.png) 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 | [![Видео](http://img.youtube.com/vi/IkhLWR_l-gM/0.jpg)](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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | ![img.png](../../../commonmedia/defaultFooter.jpg) 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 | --------------------------------------------------------------------------------