├── .gitignore ├── Algorithms ├── CodeWars │ ├── 4 kyu │ │ └── Next bigger with the same digits │ │ │ ├── Kata.java │ │ │ └── Program.java │ ├── 5 kyu │ │ ├── !String Incrementer │ │ │ ├── Kata.java │ │ │ ├── Program.java │ │ │ └── README.md │ │ └── Greed is Good │ │ │ ├── Greed.java │ │ │ ├── Program.java │ │ │ └── README.md │ └── 6 kyu │ │ ├── Create Phone Number │ │ ├── Kata.java │ │ └── README.md │ │ ├── Find the missing term in as Arithmetic Progression │ │ ├── Program.java │ │ └── Solution.java │ │ ├── GoodVsEvil │ │ ├── GoodVsEvil.java │ │ └── Program.java │ │ ├── Roman Numerals Encoder │ │ ├── Conversion.java │ │ └── Program.java │ │ └── Sort The Odd │ │ └── Kata.java └── Lists │ ├── LinkedList │ ├── LinkedList.java │ ├── LinkedListImpl.java │ └── Program.java │ └── README.md ├── Interview.md ├── JVM.md ├── Kubernetes.md ├── Notes ├── ApacheKafka │ ├── Kafka.md │ ├── img.png │ ├── img_1.png │ ├── img_10.png │ ├── img_2.png │ ├── img_3.png │ ├── img_4.png │ ├── img_5.png │ ├── img_6.png │ ├── img_7.png │ ├── img_8.png │ ├── img_9.png │ └── kafkaBook.md ├── Architecture │ ├── CleanCode.md │ ├── Patterns │ │ ├── DesignPatterns.md │ │ ├── README.md │ │ ├── facade │ │ │ ├── Car.java │ │ │ ├── Engine.java │ │ │ ├── Facade.java │ │ │ ├── Key.java │ │ │ ├── Program.java │ │ │ └── README.md │ │ ├── factory │ │ │ ├── CppDeveloper.java │ │ │ ├── CppDeveloperFactory.java │ │ │ ├── Developer.java │ │ │ ├── DeveloperFactory.java │ │ │ ├── JavaDeveloper.java │ │ │ ├── JavaDeveloperFactory.java │ │ │ ├── Program.java │ │ │ ├── PythonDeveloper.java │ │ │ ├── PythonDeveloperFabric.java │ │ │ └── README.md │ │ ├── img.png │ │ ├── img_1.png │ │ ├── img_2.png │ │ ├── img_3.png │ │ ├── img_4.png │ │ ├── img_5.png │ │ ├── img_6.png │ │ ├── img_7.png │ │ ├── img_8.png │ │ ├── img_9.png │ │ ├── prototype │ │ │ └── README.md │ │ └── singleton │ │ │ ├── README.md │ │ │ └── Singleton.java │ ├── ProgrammingPrinciples.md │ ├── REST │ │ ├── Client.java │ │ ├── ClientController.java │ │ ├── ClientService.java │ │ ├── ClientServiceImpl.java │ │ └── README.md │ └── SCRUM │ │ ├── SCRUM.md │ │ └── img │ │ └── sprint lifecycle.png ├── Databases │ ├── Configuration.md │ ├── Database.md │ └── postgreSQL │ │ ├── 1_databases.md │ │ ├── 2.1_CREATE_TABLE.md │ │ ├── 2.2_TABLES_INSERT_DELETE_UPDATE_ALTER.md │ │ ├── 3_field_types.md │ │ ├── 4.0_queries.md │ │ ├── 4.1_WHERE_querries.md │ │ ├── 4.2_GROUP_querries.md │ │ ├── 4.3_nested_querries.md │ │ ├── 5_querries_examples.md │ │ ├── 6_user_access.md │ │ ├── 7.0_links.md │ │ ├── 7.1_JOIN.md │ │ ├── 7.2_querries_multiple_tables.md │ │ ├── README.md │ │ └── perfomance.md ├── Docker │ ├── README.md │ ├── examples │ │ ├── docker-compose-app │ │ │ ├── app │ │ │ │ ├── Dockerfile │ │ │ │ └── main.py │ │ │ └── docker-compose.yml │ │ └── node-app │ │ │ ├── Dockerfile │ │ │ └── index.mjs │ └── img │ │ ├── busybox1.png │ │ └── busybox2.png ├── FlyWay │ ├── README.md │ └── img │ │ ├── plugins.png │ │ └── start.png ├── Hibernate │ ├── HIbernateCourse.md │ ├── HibernateQuerries.md │ ├── JPACriteriaQueries.md │ ├── README.md │ └── img │ │ ├── img.png │ │ ├── manyToMany.png │ │ ├── manyToOne.png │ │ ├── manyToOneJava.png │ │ ├── mtmBi.png │ │ ├── mtmMapping.png │ │ ├── mtmUni.png │ │ └── otmBi.png ├── Java │ ├── Collection │ │ ├── Program.java │ │ └── README.md │ ├── Java8 │ │ ├── lambdas │ │ │ └── README.md │ │ └── streamApi │ │ │ └── StreamApi.md │ ├── OOP.md │ ├── string │ │ ├── String.md │ │ └── assets │ │ │ └── stringPool.png │ └── threads │ │ ├── Threads.md │ │ ├── assets │ │ └── threadLifeCycle.png │ │ ├── img.png │ │ └── threads_.md ├── Spring │ ├── DataJpa │ │ ├── Spring Data Jpa.md │ │ ├── img.png │ │ └── img_1.png │ ├── Security │ │ └── README.md │ ├── Spring-reaper.md │ ├── boot │ │ ├── README.md │ │ ├── SpringBoot.md │ │ └── img.png │ ├── core │ │ ├── Annotations.md │ │ ├── Spring.md │ │ └── javaCode.md │ └── mvc │ │ └── README.md ├── Testing │ └── README.md ├── img │ ├── 1.png │ ├── 10.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png └── maven │ └── Maven.md ├── README.md ├── architecture.md ├── diagrams ├── kafak.vsdx └── kafka.vsdx ├── img.png └── todayLearned.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | out 4 | Collections/Map 5 | Algorithms/CodeWars/.idea 6 | CodeWars/*.iml 7 | CodeWars/4 kyu/*.iml 8 | CodeWars/5 kyu/*.iml 9 | CodeWars/6 kyu/*.iml 10 | Patterns/*.iml 11 | Test.java 12 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/4 kyu/Next bigger with the same digits/Kata.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | public class Kata 3 | { 4 | public static long nextBiggerNumber(long n) 5 | { 6 | char [] s = String.valueOf(n).toCharArray(); // Возвращает строковое представление аргумента 7 | for(int i = s.length - 2; i >= 0; i--){ 8 | for (int j = s.length-1; j > i; j--){ 9 | if(s[i] < s[j]){ 10 | char tmp = s[i]; 11 | s[i] = s[j]; 12 | s[j] = tmp; 13 | Arrays.sort(s, i+1, s.length); 14 | return Long.valueOf(String.valueOf(s)); 15 | } 16 | } 17 | } 18 | return -1; 19 | } 20 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/4 kyu/Next bigger with the same digits/Program.java: -------------------------------------------------------------------------------- 1 | public class Program { 2 | public static void main(String[] args) { 3 | System.out.println(Kata.nextBiggerNumber(1335)); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/5 kyu/!String Incrementer/Kata.java: -------------------------------------------------------------------------------- 1 | public class Kata { 2 | private static int countZeros(String number) { 3 | int zeroCounter = 0; 4 | for (int i = 0; i < number.length() - 1; i++) { 5 | if (number.charAt(i) != '0') { 6 | break; 7 | } 8 | zeroCounter++; 9 | } 10 | if (number.matches("0+9\\d*")) { 11 | zeroCounter -= 1; 12 | } 13 | return zeroCounter; 14 | } 15 | public static String incrementString(String str) { 16 | 17 | 18 | if (str.matches("[a-z]+[^\\d]+") || str.matches("")) { 19 | return str += "1"; 20 | } else { 21 | String stringNumber = (str.replaceAll("[^0-9]", "")); 22 | Integer zeroCounter = countZeros(stringNumber); 23 | int value = Integer.parseInt(str.replaceAll("[^0-9]", "")) + 1; 24 | return str.replaceAll("[0-9]", "") + new String(new char[zeroCounter]).replace("\0", "0") + value; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/5 kyu/!String Incrementer/Program.java: -------------------------------------------------------------------------------- 1 | public class Program { 2 | public static void main(String[] args) { 3 | System.out.println("Before 009 " + "After " + Kata.incrementString("009")); 4 | // System.out.println("Before <1&K2E^{w211680> " + "After " + Kata.incrementString("<1&K2E^{w211680>")); 5 | 6 | System.out.println("Before foobar000 " + "After " + Kata.incrementString("foobar000")); 7 | System.out.println("Before foo " + "After " + Kata.incrementString("foo")); 8 | System.out.println("Before foobar001 " + "After " + Kata.incrementString("foobar001")); 9 | System.out.println("Before foobar99 " + "After " + Kata.incrementString("foobar99")); 10 | System.out.println("Before foobar0099 " + "After " + Kata.incrementString("foobar0099")); 11 | System.out.println("Before " + "After " + Kata.incrementString("")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/5 kyu/!String Incrementer/README.md: -------------------------------------------------------------------------------- 1 | V 2 | Your job is to write a function which increments a string, to create a new string. 3 | 4 | If the string already ends with a number, the number should be incremented by 1. 5 | If the string does not end with a number. the number 1 should be appended to the new string. 6 | Examples: 7 | 8 | foo -> foo1 9 | 10 | foobar23 -> foobar24 11 | 12 | foo0042 -> foo0043 13 | 14 | foo9 -> foo10 15 | 16 | foo099 -> foo100 17 | 18 | Attention: If the number has leading zeros the amount of digits should be considered. -------------------------------------------------------------------------------- /Algorithms/CodeWars/5 kyu/Greed is Good/Greed.java: -------------------------------------------------------------------------------- 1 | public class Greed { 2 | 3 | public static int greedy(int[] dice) { 4 | int[] dieCount = new int[7]; 5 | for (int die : dice) { 6 | dieCount[die]++; 7 | } 8 | return dieCount[1]/3*1000 + dieCount[1]%3*100 + dieCount[2]/3*200 + dieCount[3]/3*300 + dieCount[4]/3*400 + dieCount[5]/3*500 + dieCount[5]%3*50 + dieCount[6]/3*600; 9 | } 10 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/5 kyu/Greed is Good/Program.java: -------------------------------------------------------------------------------- 1 | public class Program { 2 | public static void main(String[] args) { 3 | System.out.println("Score for [5,1,3,4,1] must be 250:" + Greed.greedy(new int[]{5,1,3,4,1})); 4 | System.out.println("Score for [1,1,1,3,1] must be 1100:" + Greed.greedy(new int[]{1,1,1,3,1})); 5 | System.out.println("Score for [2,4,4,5,4] must be 450:" + Greed.greedy(new int[]{2,4,4,5,4})); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/5 kyu/Greed is Good/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | Greed is a dice game played with five six-sided dice. Your mission, should you choose to accept it, is to score a throw according to these rules. You will always be given an array with five six-sided dice values. 3 | 4 | Three 1's => 1000 points 5 | Three 6's => 600 points 6 | Three 5's => 500 points 7 | Three 4's => 400 points 8 | Three 3's => 300 points 9 | Three 2's => 200 points 10 | One 1 => 100 points 11 | One 5 => 50 point 12 | A single die can only be counted once in each roll. For example, a given "5" can only count as part of a triplet (contributing to the 500 points) or as a single 50 points, but not both in the same roll. 13 | 14 | Example scoring 15 | 16 | Throw Score 17 | --------- ------------------ 18 | 5 1 3 4 1 250: 50 (for the 5) + 2 * 100 (for the 1s) 19 | 1 1 1 3 1 1100: 1000 (for three 1s) + 100 (for the other 1) 20 | 2 4 4 5 4 450: 400 (for three 4s) + 50 (for the 5) 21 | In some languages, it is possible to mutate the input to the function. This is something that you should never do. If you mutate the input, you will not be able to pass all the tests. 22 | ``` -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Create Phone Number/Kata.java: -------------------------------------------------------------------------------- 1 | public class Kata { 2 | public static String createPhoneNumber(int[] numbers) { 3 | return String.format("(%d%d%d) %d%d%d-%d%d%d%d",numbers[0],numbers[1],numbers[2],numbers[3],numbers[4],numbers[5],numbers[6],numbers[7],numbers[8],numbers[9]); 4 | } 5 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Create Phone Number/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | Write a function that accepts an array of 10 integers (between 0 and 9), that returns a string of those numbers in the form of a phone number. 3 | 4 | Example 5 | Kata.createPhoneNumber(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}) // => returns "(123) 456-7890" 6 | ``` -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Find the missing term in as Arithmetic Progression/Program.java: -------------------------------------------------------------------------------- 1 | public class Program { 2 | public static void main(String[] args) { 3 | System.out.println(Solution.findMissing(new int[]{ 1, 1, 1})); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Find the missing term in as Arithmetic Progression/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Set; 3 | import java.util.stream.Collectors; 4 | 5 | public class Solution 6 | { 7 | public static int findMissing(int[] numbers) 8 | { 9 | Set distinct = Arrays.stream(numbers).boxed().collect(Collectors.toSet()); 10 | if (distinct.size() == 1) { // Массив состоит из одинаковых элементов 11 | return numbers[0]; 12 | } 13 | int step = (numbers[numbers.length - 1] - numbers[0]) / (numbers.length); 14 | int progressionMember = numbers[0]; 15 | for (int i = 0; i < numbers.length; i++) { 16 | if (numbers[i] != progressionMember) { 17 | return progressionMember; 18 | } 19 | progressionMember += step; 20 | } 21 | return 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/GoodVsEvil/GoodVsEvil.java: -------------------------------------------------------------------------------- 1 | public class GoodVsEvil { 2 | static final int[] GOOD_ARMY = new int[] {1, 2, 3, 3, 4, 10}; 3 | static final int[] EVIL_ARMY = new int[] {1, 2, 2, 2, 3, 5, 10}; 4 | public static String battle(String goodAmounts, String evilAmounts) { 5 | 6 | int goodPower = 0; 7 | int evilPower = 0; 8 | String[] goodCounter = goodAmounts.split(" "); 9 | String[] evilCounter = evilAmounts.split(" "); 10 | 11 | for (int i = 0; i < goodCounter.length; i++) { 12 | goodPower += Integer.parseInt(goodCounter[i]) * GOOD_ARMY[i]; 13 | } 14 | for (int i = 0; i < evilCounter.length; i++) { 15 | evilPower += Integer.parseInt(evilCounter[i]) * EVIL_ARMY[i]; 16 | } 17 | if (goodPower > evilPower) { 18 | return "Battle Result: Good triumphs over Evil"; 19 | } else if (goodPower < evilPower) { 20 | return "Battle Result: Evil eradicates all trace of Good"; 21 | } 22 | return "Battle Result: No victor on this battle field"; 23 | } 24 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/GoodVsEvil/Program.java: -------------------------------------------------------------------------------- 1 | public class Program { 2 | public static void main(String[] args) { 3 | System.out.println(GoodVsEvil.battle("0 0 0 0 0 10", "0 1 1 1 1 0 0")); 4 | System.out.println(GoodVsEvil.battle("1 1 1 1 1 1", "1 1 1 1 1 1 1")); 5 | System.out.println(GoodVsEvil.battle("1 1 1 1 1 1", "1 1 1 1 1 1 1")); 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Roman Numerals Encoder/Conversion.java: -------------------------------------------------------------------------------- 1 | public class Conversion { 2 | static final String ONE = "I"; 3 | static final String FIVE = "V"; 4 | static final String TEN = "X"; 5 | static final String FIFTY = "L"; 6 | static final String HUNDRED = "C"; 7 | static final String FIVE_HUNDRED = "D"; 8 | static final String THOUSAND = "M"; 9 | public static String digitConverter(int digit) { 10 | String result = ""; 11 | if (0 < digit && digit <= 3) { 12 | result = new String(new char[digit]).replace("\0", ONE); 13 | } else if (digit == 4) { 14 | return ONE + FIVE; 15 | } else if (digit >=5 && digit < 9) { 16 | result = FIVE + new String(new char[digit - 5]).replace("\0", ONE); 17 | } else if (digit == 9) { 18 | result = ONE + TEN; 19 | } 20 | return result; 21 | } 22 | public static String dozensConverter(int dozens) { 23 | String result = ""; 24 | if (dozens <= 3) { 25 | result = new String(new char[dozens]).replace("\0", TEN); 26 | } else if (dozens == 4) { 27 | return TEN + FIFTY; 28 | } else if (dozens >= 5 && dozens < 9) { 29 | result = FIFTY + new String(new char[dozens - 5]).replace("\0", TEN); 30 | } else if (dozens == 9) { 31 | result = TEN + HUNDRED; 32 | } 33 | return result; 34 | } 35 | public static String hundredConverter(int hundred) { 36 | String result = ""; 37 | if (hundred <= 3) { 38 | result = new String(new char[hundred]).replace("\0", HUNDRED); 39 | } else if (hundred == 4) { 40 | return HUNDRED + FIVE_HUNDRED; 41 | } else if (hundred >= 5 && hundred < 9) { 42 | result = FIVE_HUNDRED + new String(new char[hundred - 5]).replace("\0", HUNDRED); 43 | } else if (hundred == 9) { 44 | result = HUNDRED + THOUSAND; 45 | } 46 | return result; 47 | } 48 | public String solution(Integer n) { 49 | String result = ""; 50 | if (n >= 1000) { 51 | Integer Mcount = n / 1000; 52 | result += new String(new char[Mcount]).replace("\0", THOUSAND); 53 | n %= 1000; 54 | } 55 | if (n >= 100) { 56 | Integer hundreds = n / 100; 57 | result += Conversion.hundredConverter(hundreds); 58 | n %= 100; 59 | } 60 | if (n >= 10) { 61 | Integer dozens = n / 10; 62 | result += Conversion.dozensConverter(dozens); 63 | n %= 10; 64 | } 65 | result += Conversion.digitConverter(n); 66 | return result; 67 | } 68 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Roman Numerals Encoder/Program.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class Program { 4 | public static int MIN = 100; 5 | public static int MAX = 1257; 6 | public static int STEP = 56; 7 | public static void main(String[] args) { 8 | Conversion conversion = new Conversion(); 9 | for (int i = 95; i < MAX; i += STEP) { 10 | System.out.println(i + " = " + conversion.solution(i)); 11 | } 12 | // System.out.println(conversion.solution(323)); 13 | } 14 | } -------------------------------------------------------------------------------- /Algorithms/CodeWars/6 kyu/Sort The Odd/Kata.java: -------------------------------------------------------------------------------- 1 | public class Kata { 2 | public static int[] sortArray(int[] array) { 3 | int temp; 4 | for (int i = 0; i < array.length; i++) { 5 | for (int j = array.length - 1; j > i; j--) { 6 | if (array[i] % 2 != 0 && array[j] % 2 != 0 && array[i] > array[j]) { 7 | temp = array[i]; 8 | array[i] = array[j]; 9 | array[j] = temp; 10 | System.out.println(array[i] + " "); 11 | } 12 | } 13 | } 14 | return array; 15 | } 16 | } -------------------------------------------------------------------------------- /Algorithms/Lists/LinkedList/LinkedList.java: -------------------------------------------------------------------------------- 1 | package Algorithms.Lists.LinkedList; 2 | 3 | public interface LinkedList { 4 | public void display(); 5 | public void add (Object data); 6 | public void add(int index, Object data); 7 | public void remove(Object data); 8 | public void remove(int index); 9 | public void set(int index, Object element); 10 | } 11 | -------------------------------------------------------------------------------- /Algorithms/Lists/LinkedList/LinkedListImpl.java: -------------------------------------------------------------------------------- 1 | package Algorithms.Lists.LinkedList; 2 | 3 | public class LinkedListImpl implements LinkedList{ 4 | Node head; 5 | Integer amount = 0; 6 | public LinkedListImpl() { 7 | head = null; 8 | } 9 | 10 | @Override 11 | public void display() { 12 | Node currentNode = head; 13 | if (head != null) { 14 | System.out.println(head.data); 15 | } 16 | while (currentNode.next != null) { 17 | currentNode = currentNode.next; 18 | System.out.println(currentNode.data); 19 | } 20 | } 21 | 22 | @Override 23 | public void add(Object data) { 24 | Node newNode = new Node(data); 25 | if (head == null) { 26 | head = newNode; 27 | } else { 28 | Node currentNode = head; 29 | while (currentNode.next != null) { 30 | currentNode = currentNode.next; 31 | } 32 | currentNode.next = newNode; 33 | newNode.previous = currentNode; 34 | } 35 | amount++; 36 | } 37 | 38 | @Override 39 | public void add(int index, Object data) { 40 | if (index > amount) { 41 | throw new RuntimeException("Index out of list"); 42 | } 43 | int i = 0; 44 | 45 | } 46 | 47 | @Override 48 | public void remove(Object data) { 49 | Node currentNode = head; 50 | Node previousNode = null; 51 | while (currentNode.next != null) { 52 | if (currentNode.data == data) { 53 | if (currentNode == head) { 54 | head = currentNode.next; 55 | } else { 56 | previousNode.next = currentNode.next; 57 | } 58 | } 59 | previousNode = currentNode; 60 | currentNode = currentNode.next; 61 | } 62 | } 63 | 64 | @Override 65 | public void remove(int index) { 66 | 67 | } 68 | 69 | @Override 70 | public void set(int index, Object element) { 71 | 72 | } 73 | 74 | private static class Node { 75 | private Object data; 76 | private Node next; 77 | public Node(Object data) { 78 | this.data = data; 79 | next = null; 80 | } 81 | 82 | public Object getData() { 83 | return data; 84 | } 85 | public Node getNext() { 86 | return next; 87 | } 88 | 89 | public void setNext(Node next) { 90 | this.next = next; 91 | } 92 | public void setData(Object data) { 93 | this.data = data; 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /Algorithms/Lists/LinkedList/Program.java: -------------------------------------------------------------------------------- 1 | package Algorithms.Lists.LinkedList; 2 | 3 | public class Program { 4 | public static void main(String[] args) { 5 | LinkedList linkedList = new LinkedListImpl(); 6 | linkedList.add(5); 7 | linkedList.add(5); 8 | linkedList.add(2); 9 | linkedList.add(3); 10 | 11 | linkedList.display(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Algorithms/Lists/README.md: -------------------------------------------------------------------------------- 1 | # Двусвязный список 2 | 3 | ## Создание связанного списка 4 | ```java 5 | Lists.LinkedList numbers = new Lists.LinkedList<>(); 6 | ``` 7 | 8 | ## Методы 9 | 10 | add() - добавление в конец списка -------------------------------------------------------------------------------- /Interview.md: -------------------------------------------------------------------------------- 1 | # Вопросы для собеседования 2 | 3 | ## Лямбда 4 | 5 | -------------------------------------------------------------------------------- /JVM.md: -------------------------------------------------------------------------------- 1 | # JDK 2 | 3 | **Notes.Java Development Kit** — разработчика приложений на языке Notes.Java, включающий в себя компилятор Notes.Java, стандартные 4 | библиотеки классов Notes.Java, примеры, документацию, различные утилиты и исполнительную систему Notes.Java. 5 | 6 | # JVM 7 | 8 | **Виртуальная машина Notes.Java (Notes.Java Virtual Machine)** - механизм, предоставляющий среду выполнения для управления Notes.Java-кодом 9 | или приложениями. Является независимой оболочкой исполнения кода, благодаря которой возможен ее запуск на любой ОС, 10 | без влияния ОС на выполняемую программу. 11 | 12 | `Notes.Java Code -> Byte Code -> Выполнение на JVM` 13 | 14 | ## За что отвечает JVM 15 | 16 | * Загрузка, проверка и исполнение байт-кода; 17 | * Предоставление среды для выполнения байт-кода; 18 | * Управление памятью и очистка мусора (Garbage Collection); 19 | 20 | ## Типы данных 21 | 22 | JVM работает с 2мя типами данных: 23 | * примитивные типы (primitive types) 24 | * ссылочные типы (reference types) 25 | 26 | ### Примитивы 27 | 28 | Типы `long` и `double`, которые являются 64-битными, поддерживаются изначально, но занимают две единицы памяти в `frame's 29 | local` или стеке операндов, поскольку каждая единица составляет 32 бита. Типы `boolean`, `byte`, `short` и `char` имеют 30 | расширенный знак (кроме `char` с нулевым расширением) и работают как 32-разрядные целые числа, так же, как и типы `int`. 31 | Меньшие типы имеют только несколько специфических для типа инструкций для загрузки, хранения и преобразования типов. 32 | `boolean` значение работает как 8-битное `byte` значения, где 0 представляет значение `false`, а 1 - значение `true`. 33 | 34 | ### Типы ссылок и значения 35 | 36 | Существует три типа ссылочных типов: типы классов, типы массивов и типы интерфейсов. Их значения являются ссылками на динамически создаваемые экземпляры классов, массивы или экземпляры классов, которые реализуют интерфейсы соответственно. 37 | 38 | -------------------------------------------------------------------------------- /Kubernetes.md: -------------------------------------------------------------------------------- 1 | # Kubernetes 2 | 3 | Оркестратор рабочей нагрузки для управления контейнерами. 4 | 5 | Микросервисная архитектура предполагает использование большого количества сервисов. Если 6 | сервис не очень высоконагруженный, то выделять под него целый сервер затратно. Поэтому для 7 | лучшей утилизации ресурсов возникла необходимость запускать несколько сервисов на одной физической 8 | или вирутальной машине. 9 | 10 | Kubernetes позволяет изолировать, конфигурировать, управлять загрузкой и работой 11 | большим количеством серверов со сложной топологией. 12 | 13 | Он гарантирует отсутствие простоев, помогает обеспечить горизонтальное и вертикальное масштабирование 14 | и межсервисное взаисодействие. 15 | 16 | ## Архитектура кластера 17 | 18 | Kubernetes разворачиватся в кластере с n-ым количеством **нод** - виртуальных или физическх машин, 19 | которые бывают 2 видов: 20 | - **управляющие ноды** - управляющий слой, отвечают за координацию распределения рабочей нагрузки по рабочим нодам; 21 | - **рабочие ноды** - полезная нагрузка, бизнес-приложения и сервисы. 22 | -------------------------------------------------------------------------------- /Notes/ApacheKafka/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_1.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_10.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_2.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_3.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_4.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_5.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_6.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_7.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_8.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/img_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/ApacheKafka/img_9.png -------------------------------------------------------------------------------- /Notes/ApacheKafka/kafkaBook.md: -------------------------------------------------------------------------------- 1 | # Apache Kafka 2 | 3 | **Apache Kafka** - это платформа потоковой передачи, которую можно использовать для большого количества 4 | событий. Причем производитель может отправить любое сообщение, даже не имея ни малейшего предстваления 5 | о том, ожидает ли эти сообщения хоть кто-нибудь. 6 | 7 | Kafka может использоваться не только в качестве **шины сообщений**, но и может при этом **обрабатывать данные 8 | в реальном времени**. 9 | 10 | Раньше микросервисы взаимодействовали друг с другом посредством API, таких как REST, 11 | но все чаще приложения строятся на том, что асинхронные **микросервисы обмениваются 12 | событиями с помощью Kafka**. 13 | 14 | ![img_4.png](img_4.png) 15 | 16 | > Kafka позволяет отделить друг от друга приложения, которые в старых проектах часто оказывались связанными 17 | Ее можно вставить в середину рабочего процесса, и она будет служить единым интерфейсом к данным вместо 18 | многочисленных API и баз данных. 19 | 20 | ### Уникальные возможности Kafka 21 | 22 | - возможность повторной передачи сообщений по умолчанию; 23 | - параллельная обработка данных; 24 | - возможность читать одно сообщение неограниченное количество раз; 25 | - возможность быстро обрабатывать большое количество сообщений за счет кеширования. 26 | 27 | ![img_3.png](img_3.png) 28 | 29 | ## Сообщения 30 | ### Доставка сообщений 31 | 32 | **Сообщение** или же **запись** - это основная часть данных, проходящих через 33 | Kafka. Собщения содержат значение, отметку времени, и **необязательный** ключ, при желании 34 | можно добавлять свои заголовки. Сгенерированные сообщения передаются брокером. 35 | 36 | Доставка сообщений в kafka может осуществляться несколькими способами 37 | - **не менее одного раза (at-least-once)** - сообщение отправляется 38 | потребителям до тех пор, пока они не подтвердят его получение. 39 | 40 | ![img.png](img.png) 41 | 42 | - **не более одного раза (at-most-once)** - сообщение отправляется только 43 | один раз и в случае сбоя н отправляется повторно.
44 | Пример использования: веб-сервис, отслеживающий количество просмотров страниц. В таком случае 45 | не критично потерять пару сообщений из миллионов. 46 | 47 | ![img_1.png](img_1.png) 48 | 49 | - **точно один раз (exactly-once)** - потребитель гарантированно получит 50 | сообщение ровно один раз. 51 | ![img_2.png](img_2.png) 52 | 53 | ## Брокер 54 | 55 | **Брокеры** - это сервера, которые отвечают за сохранение и управление данными, которые поступают в топики. 56 | **Топики** - это категории (темы), в которые данные могут быть опубликованы. 57 | Брокеры обрабатывают топки, сохраняя и управляя данными в них. 58 | 59 | ## Топики (темы) 60 | 61 | Топик состоит из одной или нескольких **партиций** (разделов), которые размещаются на брокерах 62 | (партиции разбиваются на **файлы сегментов**, которые записываются на диск). 63 | 64 | Каждая партиция имеет несколько **реплик**, и внутри этих реплик одна из них является **лидером (ведущей)**, 65 | а остальные **подписчиками лидера**. 66 | 67 | > Производители и потребители взаимодействуют только с лидером, от них 68 | он получает обновления (от производителей) / запросы на чтение (от потребителей) и передает 69 | их подписчикам в своей группе реплик в реальном времени. Если реплика-лидер становится недоступной, одна 70 | из реплик-подписчиков автоматическм выбирается в новую реплику-лидера. 71 | 72 | Каждая реплика хранится **на отдельном брокере**, партиция хранится **на отдельном брокере**. 73 | Таким образом партиция и 2 ее реплики суммарно будут хранится на 3 отдельных брокерах. 74 | 75 | ![img_7.png](img_7.png) 76 | 77 | ## Zookeper 78 | 79 | Кластер Kafka включает несколько брокеров (серверов), чтобы брокеры действовали как одно согласованное приложение, 80 | они должны не только общаться друг с другом но и достигать **согласия**. 81 | 82 | > Для обеспечения соединения между брокерами, их согласованности и координации их работы используется Zookeeper. 83 | 84 | Zookeeper играет роль узла для хранения метаданных кластера и управления состоянием брокеров. 85 | 86 | ## Высокоуровневая архитектура Kafka 87 | 88 | Кафка способна быстро обрабатывать миллионы сообщений. Одна из ключевых особенностей Kafka - **использование 89 | кеша страниц операционной системы**. **Избегая кеширования в куче JVM**, брокеры могут предотвратить некоторые 90 | проблемы, свойственные большим кучам, например, длительные или частые паузы на сборку мусора. 91 | 92 | ![img_5.png](img_5.png) 93 | 94 | **Схема доступа к данным**: благодаря обслуживанию из кеша страниц, а не с диска, сообщения **обрабатываются быстрее**. 95 | Когда поступают новые сообщения, высока вероятность, что пришедшие последними представляют больший интерес для 96 | потребителей, и, соответственно, предпочтительнее обслуживать их **быстрее (из кеша)**. 97 | 98 | ## Журнал коммитов 99 | 100 | **Журнал коммитов (фиксаций)** - место, куда последовательно добавляются сообщения. Пользователи журнала 101 | (потребители) используют **смещения (offsets)**, чтобы знать, где они находятся в этом журнале и какое сообщение 102 | они должны считать следующим для обработки. 103 | 104 | ![img.png](img_8.png) 105 | 106 | Этот механизм смещений позволяет потребителям **читать данные в своем 107 | собственном темпе** и **восстанавливать свое положение в случае сбоев или перезапусков**. 108 | 109 | > Особенность журанала коммитов: доступность только для добавления, т.е. события **всегда добавляются в конец** 110 | журнала. 111 | 112 | **Отличие кафка от других брокеров сообщений** - чтение сообщения не удаляет его из системы и не исключает 113 | из других источников. Фактически, **одно сообщение можно читать неограниченное число раз**. 114 | 115 | Хранением данных в журнале можно управлять по размеру или возврасту сообщениЙ с помощью свойств конфигурации. 116 | 117 | ## Потоковая обработка данных 118 | 119 | Производители отправляют данные в Kafka, которая для надежности и масштабируемости действует как 120 | распределенная система и использует журналы как основные хранилища. 121 | 122 | Как только данные попадут в экосистему Kafka, потребители смогут помочь пользователям получить их в других 123 | приложениях и сценариях использования. 124 | 125 | Брокеры объединятся в кластер и координируют свои действия при помощи Zookeeper. 126 | 127 | Поскольку Kafka хранит данные на диске, осуществляется поддержка воспроизведения сообщений в случае сбоя приложений. 128 | 129 | ![img_2.png](img_10.png) 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | # Kafka Connect 231 | 232 | **Kafka Connect** - фреймворк, позволяющий экспортировать данные из хранилища, например, базы данных в Kafka. 233 | 234 | **Коннекторы-источники** преобразовыввают данные в сообщения Kafka (например, таблицы MySQL в темы Kafka). 235 | 236 | **Коннекторы-приемники** используются для импорта данных из Kafka в другие системы. Например, переместить сообщения из 237 | какой-то темы в долговременное хранилище можо с помощью коннектора-приемника, который будет излекать сообщения из темы 238 | и записывать их, к примеру, в облачное хранилище. 239 | 240 | ![img_1.png](img_9.png) 241 | 242 | 243 | # Безопасность 244 | 245 | ## SSL 246 | 247 | SSL - Secure Socket Layer - протокол шифрования сообщений. При шифровании посторонние пользователи могут видеть 248 | трафик, но не смогут понять его содержимое. 249 | 250 | Для настройки шифрования сетевого трафика между кластерами необходимы ключ и сертифкат для брокеров. 251 | 252 | keystore.jks - имя хранилища ключей, куда должен быть помещен сгнерированный ключ (ключ играет роль идентификации 253 | для брокеров). 254 | 255 | truststore.jks - хранилище доверенных сертификатов (подтверждают, что ключ подлинный) 256 | 257 | ## Kerberos и Simple Authentication and Security Layer 258 | 259 | JAAS - Java Authentication and Authorization Service - сервис аутентификации и авторизации. 260 | 261 | Файлы JAAS с информацией о файле keytab помогают передать в Kafka принципала (уикальное имя учетной записи) 262 | и учетные данные. keytab - файл, содержащий принципала и зашифровнные ключи, он используется для аутентификации 263 | брокеров Kafka без запроса пароля. -------------------------------------------------------------------------------- /Notes/Architecture/CleanCode.md: -------------------------------------------------------------------------------- 1 | # Чистый код по Р. Мартину 2 | 3 | Классы и переменные - существительные, методы и интерфейсы - глаголы. 4 | 5 | 6 | 7 | --- 8 | 9 | ## Объекты и структуры 10 | 11 | >Название - существительное по состоянию классу(то, что он содержит). 12 | 13 | **Отличие между объектом и структурой данных** заключается в том, что в объекте содержится состояние и поведение, в структуре 14 | данных содержится только состояние. 15 | 16 | **Закон Деметры:** никакой объект не должен раскрывать свою внутреннюю структуру тем, кто к нему обращается. Все манипуляции 17 | с объектом должны содержаться в методах данного объекта. 18 | 19 | --- 20 | 21 | ## Форматирование класса 22 | 1. Класс; 23 | 2. Документация по классу; 24 | 3. Поля по убыванию важности, начиная с id; 25 | 4. Конструкторы; 26 | 5. public методы; 27 | 6. private методы; 28 | 29 | Добавлять пропуски между концепциями (блоками методов) 30 | 31 | --- 32 | 33 | ## Методы 34 | - Один метод - одна задача, один уровень абстракции на метод; 35 | - Выносить код из `switch` в `enum`; 36 | - Описательные имена (глаголы); 37 | - Чем меньше входных параметров - тем лучше. **Если у метода больше 3 аргументов** - создавать параметр `Object` 38 | (Например, объединить `dateStart` и `dateEnd` в объект `DateRange`, после чего для объекта реализовать методы; 39 | - Клиентский код не должен создавать флаги, влияющие на серверный код (нарушается инкапсуляция и читабельность кода); 40 | - **Менять объект** может только `void`; 41 | - Функция, возвращающее **булево значение**, имеет приставку `is`. 42 | 43 | 44 | 45 | --- 46 | 47 | ## Комментарии 48 | 49 | - Legal Info (автор, дата, копирайт); 50 | - Контринтуитивное поведение или нелогичное поведение системы при определенном бизнес-процессе; 51 | - Комментарий к запутанной части кода (перед или внутри `RegEx`, или запутанная бизнес-логика); 52 | - Предупреждение о последствиях (если это удалить, кусок кода работать не будет; не удалять, 53 | иначе будут такие последствия); 54 | - TODO; 55 | - **Javadoc** - оформление документации к коду. Документация пишется только по `public` методам; 56 | - Использовать метод / переменную вместо комментария (увеличение переменной на определенное значение вывести в метод, 57 | в названии пояснить, что связано с бизнес-задачей); 58 | 59 | --- 60 | 61 | # Обработка ошибок (Error handling) 62 | - Использовать исключения, а не коды возврата; 63 | - Ловим только `Exceptions`; 64 | - Весь код должен входить в блок `try-catch-finally`; 65 | - Прописывать для каждого слоя свое исключение (`UiException`, `BusinessLogicException`), 66 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/DesignPatterns.md: -------------------------------------------------------------------------------- 1 | План: 2 | 1. Архитектура кода как часть архитектуры приложения 3 | 2. Что такое шаблоны проектирования приложения (паттерны)? 4 | 3. Зачем нужны шаблоны проектирования? 5 | 3. Виды шаблонов проектирования 6 | - Порождающие 7 | - Поведенчиские 8 | - Структурные 9 | 4. Антипаттерны 10 | 11 | --- 12 | 13 | > Приветствие. С чего начинается разработка приложения? (Веду к проектированию архитектуры приложения) 14 | 15 | # Способы организации кода кода | Архитектура приложения 16 | 17 | > Что такое архитектура приложения? Можно ли отнести код к архитектуре приложения? 18 | 19 | **Архитектура приложения** - крупная система, включающая компоненты кода, различные слои приложения и их взамодействия. 20 | 21 | ![img.png](img.png) 22 | 23 | # Шаблоны проектирования | Design Patterns 24 | 25 | > Предположим, вам нужно решить задачу, у вас есть какие-то требования 26 | > с чего начнете разработку? 27 | > 28 | > 29 | > Смысл в том, что при разрешении какого-либо вопроса в разработке скорее всего, до вас с этим уже кто-то сталкивался, 30 | > причем не один раз и уже какие-то рецепты решения проблемы. Так что, вместо того, чтобы изобретать свой велосипед лучше 31 | > попробовать воспользоваться уже разработанными шаблонами проектирования 32 | 33 | **Шаблоны проектирования** - это проверенные и готовые к использованию решения регулярно возникающих в повседневном программировании задач. 34 | Используются для ускорения проектирования и последующей разработки приложений. 35 | 36 | ## Виды паттернов 37 | 38 | Выделяют три типа паттернов: 39 | - **Порождающие** - представляют собой механизмы инициализации, позволяют создавать объекты удобным способом. 40 | - **Структурные** - определяют отношения между классами и объектами, позволяя им работать совместно. 41 | - **Поведенческие** - упрощают взаимодействие между сущностями. 42 | 43 | ![img_1.png](img_1.png) 44 | 45 | # Порождающие 46 | 47 | **Порождающие шаблоны проектирования** используются для управления процессом создания объектов, делая систему независимой от 48 | способа создания, композиции и представления объектов. 49 | 50 | 51 | Они обеспечивают гибкость при решении вопросов о том, 52 | что создается, кто это создает, как и когда. 53 | 54 | Эти шаблоны позволяют инкапсулировать процесс создания объектов, 55 | скрывая детали реализации и обеспечивая возможность выбора между различными способами создания объектов. 56 | 57 | ## Примеры порождающих паттернов 58 | 59 | > Лайф-коддинг сессия, каждый паттерн 60 | 61 | ### **Фабричный метод | Simple Factory (Factory Method)** 62 | Простой в реализации порождающий паттерн, который инкапсулирует процесс создания объектов с помощью отдельного класса-фабрики. 63 | 64 | **Используется**, когда у нас есть суперкласс с несколькими подклассами и на основе ввода, нам нужно вернуть один из подкласса. 65 | Класс не знает какого типа объект он должен создать. Объекты создаются "на лету" в зависимости от входящих данных. 66 | 67 | ![img_3.png](img_3.png) 68 | 69 | ```java 70 | class Factory { 71 | public OS getCurrentOS(String inputos) { 72 | OS os = null; 73 | if (inputos.equals("windows")) { 74 | os = new windowsOS(); 75 | } else if (inputos.equals("linux")) { 76 | os = new linuxOS(); 77 | } else if (inputos.equals("mac")) { 78 | os = new macOS(); 79 | } 80 | return os; 81 | } 82 | } 83 | interface OS { 84 | void getOS(); 85 | } 86 | class windowsOS implements OS { 87 | public void getOS () { 88 | System.out.println("применить для виндовс"); 89 | } 90 | } 91 | class linuxOS implements OS { 92 | public void getOS () { 93 | System.out.println("применить для линукс"); 94 | } 95 | } 96 | class macOS implements OS { 97 | public void getOS () { 98 | System.out.println("применить для мак"); 99 | } 100 | } 101 | 102 | public class FactoryTest {//тест 103 | public static void main(String[] args){ 104 | String win = "linux"; 105 | Factory factory = new Factory(); 106 | OS os = factory.getCurrentOS(win); 107 | os.getOS(); 108 | } 109 | } 110 | ``` 111 | 112 | ### Singleton | Одиночка 113 | 114 | **Singleton**: Одиночка - паттерн, который гарантирует, что в системе существует только один экземпляр класса и предоставляет глобальную точку доступа к этому экземпляру. 115 | 116 | ![img_2.png](img_2.png) 117 | 118 | ### Abstract Factory | Абстрактная фабрика 119 | 120 | **Abstract Factory**: Абстрактная фабрика - паттерн, предоставляющий интерфейс для создания семейств взаимосвязанных 121 | или взаимозависимых объектов, без указания их конкретных классов. 122 | 123 | Позволяет выбрать конкретную реализацию фабрики из семейства возможных фабрик. Создает семейство связанных объектов. Легко расширять. 124 | 125 | ![img_5.png](img_5.png) 126 | 127 | 128 | ### Builder | Строитель 129 | 130 | **Builder**: Строитель - паттерн, который позволяет создавать разные виды объектов с использованием одного и того же процесса построения. 131 | 132 | Используется для создания сложного объекта с использованием простых объектов. 133 | Постепенно он создает больший объект от малого и простого объекта. Позволяет изменять внутреннее представление конечного 134 | продукта. 135 | 136 | ![img_4.png](img_4.png) 137 | 138 | # Поведенческие 139 | 140 | ### Шаблонный метод | Template Method 141 | 142 | Позволяет определить основу алгоритма и позволяющий подклассам переопределять определенные шаги алгоритма, не изменяя его структуру в целом. 143 | 144 | 145 | ![img_6.png](img_6.png)eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 146 | 147 | ### Chain of Responsibility | Цепочка обязанностей 148 | 149 | Позволяет избежать жесткой зависимости отправителя запроса от его получателя, при этом запрос может быть обработан несколькими объектами. 150 | 151 | ![img_7.png](img_7.png) 152 | 153 | ## Observer | Наблюдатель 154 | Позволяет одним объектам наблюдать за действиями что происходят в других объектах. 155 | 156 | 157 | ![img_8.png](img_8.png) 158 | 159 | ## Command | Команда 160 | 161 | Позволяет инкапсулировать различные операции в отдельные объекты. 162 | 163 | ![img_9.png](img_9.png) 164 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/README.md: -------------------------------------------------------------------------------- 1 | # Шаблоны проектирования 2 | 3 | Выделяют три типа паттернов: 4 | - **Порождающие** - представляют собой механизмы инициализации, позволяют создавать объекты удобным способом. 5 | - **Структурные** - определяют отношения между классами и объектами, позволяя им работать совместно. 6 | - **Поведенческие** - упрощают взаимодействие между сущностями. 7 | 8 | 9 | 10 | ## Порождающие 11 | 12 | - [singleton (Одиночка)](singleton/) - ограничивает создание одного экземпляра класса, обеспечивает доступ к его единственному объекту. 13 | 14 | - [factory (Фабрика)](factory/) - используется, когда у нас есть суперкласс с несколькими подклассами и на основе ввода, нам нужно вернуть один из подкласса. 15 | - **Abstract factory (Абстрактная фабрика)** - используем супер фабрику для создания фабрики, затем используем созданную фабрику для создания объектов. 16 | - **Builder (Строитель)** - используется для создания сложного объекта с использованием простых объектов. Постепенно он создает больший объект от малого и простого объекта. 17 | - **Prototype (Прототип)** - помогает создать дублированный объект с лучшей производительностью, вместо нового создается возвращаемый клон существующего объекта. 18 | 19 | 20 | 21 | ## Структурные 22 | 23 | * Adapter (Адаптер) - это конвертер между двумя несовместимыми объектами. Используя паттерн адаптера, мы можем объединить два несовместимых интерфейса. 24 | * Composite (Компоновщик) - использует один класс для представления древовидной структуры. 25 | * Proxy (Заместитель) - представляет функциональность другого класса. 26 | * Flyweight (Легковес) - вместо создания большого количества похожих объектов, объекты используются повторно. 27 | * [facade (Фасад)](facade/) - беспечивает простой интерфейс для клиента, и клиент использует интерфейс для взаимодействия с системой. 28 | * Bridge (Мост) - делает конкретные классы независимыми от классов реализации интерфейса. 29 | * Decorator (Декоратор) - добавляет новые функциональные возможности существующего объекта без привязки его структуры. 30 | 31 | 32 | 33 | ## Поведенческие 34 | 35 | * Template Method (Шаблонный метод) - определяющий основу алгоритма и позволяющий наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом. 36 | * Mediator (Посредник) - предоставляет класс посредника, который обрабатывает все коммуникации между различными классами. 37 | * Chain of Responsibility (Цепочка обязанностей) - позволяет избежать жесткой зависимости отправителя запроса от его получателя, при этом запрос может быть обработан несколькими объектами. 38 | * Observer (Наблюдатель) - позволяет одним объектам следить и реагировать на события, происходящие в других объектах. 39 | * Strategy (Стратегия) - алгоритм стратегии может быть изменен во время выполнения программы. 40 | * Command (Команда) - интерфейс команды объявляет метод для выполнения определенного действия. 41 | * State (Состояние) - объект может изменять свое поведение в зависимости от его состояния. 42 | * Visitor (Посетитель) - используется для упрощения операций над группировками связанных объектов. 43 | * Interpreter (Интерпретатор) - определяет грамматику простого языка для проблемной области. 44 | * Iterator (Итератор) - последовательно осуществляет доступ к элементам объекта коллекции, не зная его основного представления. 45 | * Memento (Хранитель) - используется для хранения состояния объекта, позже это состояние можно восстановить. -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/facade/Car.java: -------------------------------------------------------------------------------- 1 | public interface Car { 2 | void start(); 3 | void stop(); 4 | } 5 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/facade/Engine.java: -------------------------------------------------------------------------------- 1 | class Engine implements Car { 2 | public void start() { 3 | System.out.println("Запустить двигатель"); 4 | } 5 | public void stop() { 6 | System.out.println("Остановить двигатель"); 7 | } 8 | } -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/facade/Facade.java: -------------------------------------------------------------------------------- 1 | class Facade { 2 | private Key key; 3 | private Engine engine; 4 | public Facade() { 5 | key = new Key(); 6 | engine = new Engine(); 7 | } 8 | public void startCar() { 9 | key.start(); 10 | engine.start(); 11 | } 12 | public void stoptCar() { 13 | key.stop(); 14 | engine.stop(); 15 | } 16 | } -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/facade/Key.java: -------------------------------------------------------------------------------- 1 | class Key implements Car { 2 | public void start() { 3 | System.out.println("Вставить ключи"); 4 | } 5 | public void stop() { 6 | System.out.println("Вытянуть ключи"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/facade/Program.java: -------------------------------------------------------------------------------- 1 | public class Program { 2 | public static void main(String[] args) { 3 | Facade facade = new Facade(); 4 | facade.startCar(); 5 | System.out.println(); 6 | facade.stoptCar(); 7 | } 8 | } -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/facade/README.md: -------------------------------------------------------------------------------- 1 | # facade - Фасад 2 | 3 | Скрывает сложную систему классов приводя все вызовы к одному объекту. Помещает вызов нескольких сложных объектов в один объект. 4 | 5 | **Вкратце**: Как включить компьютер? Вы скажете: «Нажать кнопку включения». Это потому, что вы используете простой интерфейс, предоставляемый компьютером наружу. 6 | А внутри него происходит очень много процессов. Простой интерфейс для сложной подсистемы — это фасад. 7 | 8 | **Аналогия**: Как включить компьютер? Вы скажете: «Нажать кнопку включения». Это потому, что вы используете простой интерфейс, предоставляемый компьютером наружу. 9 | А внутри него происходит очень много процессов. Простой интерфейс для сложной подсистемы — это фасад 10 | 11 | **Пример использования:** упрощеный интерфейс для более крупного тела кода, например, библиотеки классов. -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/CppDeveloper.java: -------------------------------------------------------------------------------- 1 | public class CppDeveloper implements Developer{ 2 | @Override 3 | public void writeCode() { 4 | System.out.println("Cpp Developer writes Cpp code..."); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/CppDeveloperFactory.java: -------------------------------------------------------------------------------- 1 | public class CppDeveloperFactory implements DeveloperFactory{ 2 | @Override 3 | public Developer createDeveloper() { 4 | return new CppDeveloper(); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/Developer.java: -------------------------------------------------------------------------------- 1 | public interface Developer { 2 | void writeCode(); 3 | } 4 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/DeveloperFactory.java: -------------------------------------------------------------------------------- 1 | public interface DeveloperFactory { 2 | Developer createDeveloper(); 3 | } 4 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/JavaDeveloper.java: -------------------------------------------------------------------------------- 1 | public class JavaDeveloper implements Developer{ 2 | @Override 3 | public void writeCode() { 4 | System.out.println("Notes.Java Developer writes Notes.Java code..."); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/JavaDeveloperFactory.java: -------------------------------------------------------------------------------- 1 | public class JavaDeveloperFactory implements DeveloperFactory{ 2 | @Override 3 | public Developer createDeveloper() { 4 | return new JavaDeveloper(); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/Program.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class Program { 4 | public static void main(String[] args) { 5 | Scanner scanner = new Scanner(System.in); 6 | DeveloperFactory developerFactory = createDeveloperBySpecialty(scanner.nextLine()); 7 | Developer developer = developerFactory.createDeveloper(); 8 | developer.writeCode(); 9 | } 10 | 11 | static DeveloperFactory createDeveloperBySpecialty(String specialty) { 12 | if (specialty.equalsIgnoreCase("java")) { 13 | return new JavaDeveloperFactory(); 14 | } else if (specialty.equalsIgnoreCase("cpp")) { 15 | return new CppDeveloperFactory(); 16 | } else if (specialty.equalsIgnoreCase("python")) { 17 | return new PythonDeveloperFabric(); 18 | } else { 19 | throw new RuntimeException(specialty + " is unknown specialty"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/PythonDeveloper.java: -------------------------------------------------------------------------------- 1 | public class PythonDeveloper implements Developer{ 2 | @Override 3 | public void writeCode() { 4 | System.out.println("Python Developer writes Python code..."); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/PythonDeveloperFabric.java: -------------------------------------------------------------------------------- 1 | public class PythonDeveloperFabric implements DeveloperFactory { 2 | @Override 3 | public Developer createDeveloper() { 4 | return new PythonDeveloper(); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/factory/README.md: -------------------------------------------------------------------------------- 1 | # factory - Фабрика - Фабричный метод 2 | 3 | **Вкратце**: Это способ делегирования логики создания объектов (instantiation logic) дочерним классам. 4 | Суть способа заключается в том, что объекты создаются посредством вызова не конструктора, а генерирующего метода, 5 | определенного в интерфейсе и реализованного дочерними классами. 6 | 7 | **Аналогия**: Одна кадровичка не в силах провести собеседования со всеми кандидатами на все должности. В зависимости от вакансии она может делегировать разные этапы собеседований разным сотрудникам. 8 | 9 | **Пример использования:** заранее неизвестно, экземпляры какого класса нужно будет создавать. 10 | 11 | **Реализация:** 12 | 1. Реализация отдельных нужных нам объектов. (Классы `JavaDeveloper`, `CppDeveloper` и `PythonDeveloper`). 13 | 2. Реализация интерфейса с генерирующим методом (Интерфейс `DeveloperFactory`). 14 | 3. Реализация классов-фабрик, наследующих интерфейс и возвращающих свежесозданный объект 15 | ```java 16 | public class CppDeveloperFactory implements DeveloperFactory{ 17 | @Override 18 | public Developer createDeveloper() { 19 | return new CppDeveloper(); 20 | } 21 | } 22 | ``` 23 | 4. Реализация в коде статического метода, который в зависимости от условия создает фабрику 24 | ```java 25 | static DeveloperFactory createDeveloperBySpecialty(String specialty) { 26 | if (specialty.equalsIgnoreCase("java")) { 27 | return new JavaDeveloperFactory(); 28 | } else if (specialty.equalsIgnoreCase("cpp")) { 29 | return new CppDeveloperFactory(); 30 | } else if (specialty.equalsIgnoreCase("python")) { 31 | return new PythonDeveloperFabric(); 32 | } else { 33 | throw new RuntimeException(specialty + " is unknown specialty"); 34 | } 35 | } 36 | ``` 37 | 5. Создание в коде фабрики и ее продукта 38 | ```java 39 | DeveloperFactory developerFactory = createDeveloperBySpecialty(scanner.nextLine()); 40 | Developer developer = developerFactory.createDeveloper(); 41 | ``` -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_1.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_2.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_3.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_4.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_5.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_6.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_7.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_8.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/img_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/Patterns/img_9.png -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/prototype/README.md: -------------------------------------------------------------------------------- 1 | # Prototype - Прототип 2 | 3 | **Вкратце**: Объект создаётся посредством клонирования существующего объекта. 4 | 5 | **Пример использования:** когда необходимый объект аналогичен уже существующему или когда создание с нуля дороже клонирования. 6 | 7 | -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/singleton/README.md: -------------------------------------------------------------------------------- 1 | # singleton (Одиночка) 2 | 3 | **Вкратце**: Шаблон позволяет удостовериться, что создаваемый объект — единственный в своём классе. 4 | **Аналогия**: У страны может быть только один президент. Он должен действовать, когда того требуют обстоятельства и долг. В данном случае президент — одиночка. 5 | 6 | >Шаблон «Одиночка» позволяет ограничивать создание класса единственным объектом. Это удобно, когда для координации действий в рамках системы требуется, чтобы объект был единственным в своём классе. 7 | 8 | **Минусы шаблона:** вносит в приложение глобальное состояние, так что изменение в одном месте может повлиять на все остальные случаи использования, может быть сложным в отладке. 9 | Делает код сильно связанным `(tightly coupled)`, а создание прототипа `(mocking)` «Одиночки» может быть затруднено. -------------------------------------------------------------------------------- /Notes/Architecture/Patterns/singleton/Singleton.java: -------------------------------------------------------------------------------- 1 | package singleton; 2 | 3 | public class Singleton { 4 | private static Singleton instanse = null; // Статический объект 5 | private Singleton() {} 6 | public static Singleton getInstance() { 7 | if (instanse == null) { 8 | instanse = new Singleton(); 9 | } 10 | return instanse; 11 | } 12 | 13 | public static void main(String[] args) { 14 | Singleton singleton = Singleton.getInstance(); // Получение объекта через геттер 15 | } 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /Notes/Architecture/ProgrammingPrinciples.md: -------------------------------------------------------------------------------- 1 | # Принципы программирования 2 | 3 | 4 | 5 | # DRY - Don’t repeat yourself 6 | 7 | Все данные, входящие в систему должны иметь одно представление. 8 | 9 | Следование принципу DRY всегда приводит к декомпозиции сложных алгоритмов на простые функции. 10 | А декомпозиция сложных операций на более простые (и повторно используемые) значительно упрощает понимание программного кода. 11 | Повторное использование функций, вынесенных из сложных алгоритмов, позволяет сократить время разработки и тестирования новой функциональности. 12 | 13 | --- 14 | 15 | 16 | 17 | # YAGNI - You aren't gonna need it 18 | 19 | Возможности, не описанные в системе, не должны реализовываться. 20 | - Заказчик не должен оплачивать ненужный ему функционал; 21 | - Разработчик не должен принимать решения за заказчика; 22 | - Бесплатных функций в программных продуктах не бывает; 23 | 24 | Нежелательные последствия: 25 | - Тратится время, которое могло бы быть задействовано на нужные функции; 26 | - Новые функции должны быть отлажены, задокументированы и сопровождены; 27 | - Новая необязательная функциональность может ограничивать функциональность, которая будет добавлена в будущем; 28 | - Антипаттерн SoftCode (малейшее действие требует конфигурации); 29 | 30 | --- 31 | 32 | 33 | 34 | ## KISS - Keep It Simple, Stupid (Keep It Simple and Smart) 35 | - Код должен иметь наименьшее необходимое количество классов и методов; 36 | - Не имеет смысла реализовывать дополнительные функции без необходимости; 37 | - Не стоит перегружать интерфейс теми опциями, которые не будут нужны большинству пользователей; 38 | - Бессмысленно делать реализацию сложной бизнес-логики, которая учитывает абсолютно все возможные варианты; 39 | - Не имеет смысла беспредельно увеличивать уровень абстракции; 40 | - Бессмысленно закладывать в проект избыточные функции «про запас»; 41 | - Не стоит подключать огромную библиотеку, если вам от неё нужна лишь пара функций; 42 | - Абсолютная математическая точность или предельная детализация нужны не всегда; 43 | - Принципы простого дизайна от Кента Бека (все тесты запускаются, отсутствует дублирование логики, явны намерения программиста); 44 | --- 45 | 46 | 47 | 48 | # Принципы SOLID 49 | - `S - Single responsibility` - принцип единственности ответственности; 50 | - `O - Open-closed` - принцип открытости/закрытости; 51 | - `L - Liskov substitution` - принцип подстановки Барбары Лисков; 52 | - `I - Interface segregation` - принцип разделения интерфейсов; 53 | - `D - Dependency inversion` - принцип инверсии зависимостей; 54 | 55 | > Позволяют строить на базе ООП масштабируемые и сопровождаемые программные продукты с понятной бизнес-логикой. 56 | 57 | 58 | 59 | ## Single responsibility principle / SRP 60 | 61 | Каждый объект должен иметь одну обязанность и эта обязанность должна быть полностью инкапсулирована в класс. Все его сервисы должны быть направлены исключительно на обеспечение этой обязанности. 62 | 63 | Следование принципу: 64 | 1. Разделение больших классов с большим количеством функционала; 65 | 2. Слияние мелких классов и объединение в одном классе однотипной функциональности; 66 | 3. Упрощает поддержку и расширение классов; 67 | 4. Антипаттерны - типа GoD object; 68 | 5. Требует осмысленного отношения; 69 | 6. Active Record нарушает SRP; 70 | 71 | 72 | 73 | ## Open-closed principle / OCP 74 | 75 | Программные сущности (классы, модули, функции и т. п.) должны быть открыты для расширения, но закрыты для изменения. Это означает, что эти сущности могут менять свое поведение без изменения их исходного кода. 76 | 77 | Однажды разработанная реализация класса в дальнейшем требует только исправления ошибок, а новые или изменённые функции требуют создания нового класса. Реализация интерфейса может быть унаследована и переиспользована, но интерфейс может и измениться в новой реализации. 78 | 79 | Полиморфный принцип открытости/закрытости: 80 | 81 | 1. Основывается на строгой реализации интерфейсов и на наследовании от абстрактных базовых классов или на полиморфизме. 82 | 2. Созданный изначально интерфейс должен быть закрыт для модификаций, а новые реализации как минимум соответствуют этому изначальному интерфейсу, но могут поддерживать и другие, более расширенные. 83 | 84 | 85 | 86 | ## Liskov substitution / LSP 87 | 88 | Объекты в программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы. Код обрабатывающий базовый класс, должен иметь возможность обрабатывать любого наследника базового класса. 89 | 90 | Частое нарушение - бросание исключений в неподдерживаемых методах. 91 | 92 | 93 | 94 | ## Interface segregation principle / ISP 95 | 96 | Много интерфейсов, специально предназначенных для клиентов, лучше, чем один интерфейс общего назначения. Клиенты не должны зависеть от методов, которые они не используют. 97 | 1. в формулировке Роберта Мартина декларирует, что клиенты не должны зависеть от методов, которые они не используют. То есть если какой-то метод интерфейса не используется клиентом, то изменения этого метода не должны приводить к необходимости внесения изменений в клиентский код. 98 | 2. Следование принципу ISP заключается в создании интерфейсов, которые достаточно специфичны и требуют только необходимый минимум реализаций методов 99 | 3. Избыточные интерфейсы, напротив, могут требовать от реализующего класса создание большого количества методов, причём даже таких, которые не имеют смысла в контексте класса. 100 | 4. перекликается с принципом единственной ответственности 101 | 5. снижает сложность поддержки и развития приложения 102 | 6. Чем проще и минималистичнее используемый интерфейс, тем менее ресурсоёмкой является его реализация в новых классах, тем меньше причин его модифицировать 103 | 104 | ## Dependency inversion principle / DIP 105 | 106 | - Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций. 107 | - Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. 108 | 109 | Все классы должны использоваться через интерфейсы (при случаях, когда один класс использует другой). -------------------------------------------------------------------------------- /Notes/Architecture/REST/Client.java: -------------------------------------------------------------------------------- 1 | package Notes.Architecture.REST; 2 | 3 | public class Client { 4 | 5 | private Integer id; 6 | private String name; 7 | private String email; 8 | private String phone; 9 | 10 | public Integer getId() { 11 | return id; 12 | } 13 | 14 | public void setId(Integer id) { 15 | this.id = id; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public String getEmail() { 27 | return email; 28 | } 29 | 30 | public void setEmail(String email) { 31 | this.email = email; 32 | } 33 | 34 | public String getPhone() { 35 | return phone; 36 | } 37 | 38 | public void setPhone(String phone) { 39 | this.phone = phone; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Notes/Architecture/REST/ClientController.java: -------------------------------------------------------------------------------- 1 | package Notes.Architecture.REST; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | @RestController 11 | public class ClientController { 12 | private final ClientService clientService; 13 | 14 | @Autowired 15 | public ClientController(ClientService clientService) { 16 | this.clientService = clientService; 17 | } 18 | 19 | @PostMapping(value = "/clients") 20 | public ResponseEntity create(@RequestBody Client client) { 21 | clientService.create(client); 22 | return new ResponseEntity<>(HttpStatus.CREATED); 23 | } 24 | 25 | @GetMapping(value = "/clients") 26 | public ResponseEntity> read() { 27 | final List clients = clientService.readAll(); 28 | return clients != null && !clients.isEmpty() 29 | ? new ResponseEntity<>(clients, HttpStatus.OK) 30 | : new ResponseEntity<>(HttpStatus.NOT_FOUND); 31 | } 32 | 33 | @GetMapping(value = "/clients/{id}") 34 | public ResponseEntity read(@PathVariable(name = "id") int id) { 35 | final Client client = clientService.read(id); 36 | return client != null 37 | ? new ResponseEntity<>(client, HttpStatus.OK) 38 | : new ResponseEntity<>(HttpStatus.NOT_FOUND); 39 | } 40 | 41 | @PutMapping(value = "/clients/{id}") 42 | public ResponseEntity update(@PathVariable(name = "id") int id, @RequestBody Client client) { 43 | final boolean updated = clientService.update(client, id); 44 | return updated 45 | ? new ResponseEntity<>(HttpStatus.OK) 46 | : new ResponseEntity<>(HttpStatus.NOT_MODIFIED); 47 | } 48 | 49 | @DeleteMapping(value = "/clients/{id}") 50 | public ResponseEntity delete(@PathVariable(name = "id") int id) { 51 | final boolean deleted = clientService.delete(id); 52 | return deleted 53 | ? new ResponseEntity<>(HttpStatus.OK) 54 | : new ResponseEntity<>(HttpStatus.NOT_MODIFIED); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Notes/Architecture/REST/ClientService.java: -------------------------------------------------------------------------------- 1 | package Notes.Architecture.REST; 2 | 3 | import java.util.List; 4 | 5 | public interface ClientService { 6 | void create(Client client); 7 | List readAll(); 8 | Client read(int id); 9 | boolean update(Client client, int id); 10 | boolean delete(int id); 11 | } 12 | -------------------------------------------------------------------------------- /Notes/Architecture/REST/ClientServiceImpl.java: -------------------------------------------------------------------------------- 1 | package Notes.Architecture.REST; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | @Service 12 | public class ClientServiceImpl implements ClientService{ 13 | private static final Map CLIENT_REPOSITORY_MAP = new HashMap<>(); 14 | private static final AtomicInteger CLIENT_ID_HOLDER = new AtomicInteger(); 15 | 16 | @Override 17 | public void create(Client client) { 18 | final int clientID = CLIENT_ID_HOLDER.incrementAndGet(); 19 | client.setId(clientID); 20 | CLIENT_REPOSITORY_MAP.put(clientID,client); 21 | } 22 | 23 | @Override 24 | public List readAll() { 25 | return new ArrayList<>(CLIENT_REPOSITORY_MAP.values()); 26 | } 27 | 28 | @Override 29 | public Client read(int id) { 30 | return CLIENT_REPOSITORY_MAP.get(id); 31 | } 32 | 33 | @Override 34 | public boolean update(Client client, int id) { 35 | if (CLIENT_REPOSITORY_MAP.containsKey(id)) { 36 | client.setId(id); 37 | CLIENT_REPOSITORY_MAP.put(id, client); 38 | return true; 39 | } 40 | return false; 41 | } 42 | 43 | @Override 44 | public boolean delete(int id) { 45 | return CLIENT_REPOSITORY_MAP.remove(id) != null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Notes/Architecture/REST/README.md: -------------------------------------------------------------------------------- 1 | # REST 2 | 3 | * [Ограничения и принципы](#principles) 4 | * [Коммуникаия между клиентом и сервером](#communcation) 5 | * [URI и ресурсы](#URIResources) 6 | * [Примеры HTTP запросов](#examples) 7 | 8 | **REST - Representational State Transfer (передача состояния представления)** - архитектурный стиль обмена 9 | данными между разными компонентами системы, каждая из которых может физически располагаться в разных местах. 10 | 11 | Представляет собой согласованный набор ограничений, учитываемых при проектировании удаленной системы. 12 | 13 | ### Преимущества 14 | 15 | - надежность в виде отсутствия необходимости сохранять информацию о состояни клиентов; 16 | - производительность за счет использования кэша; 17 | - масштабируемость; 18 | - прозрачность системы взаимодействия; 19 | - простота интерфейсов; 20 | - портативность компонентов; 21 | - легкость внесения изменений; 22 | 23 | 24 | 25 | ## REST ограничения и принципы 26 | 27 | В общем случае компоненты распределенной системы взаимодействуют друг с другом посредством запросов-ответов по 28 | протоколу HTTP. 29 | 30 | ### 1. Приведение архитектуры к модели клиент-сервер 31 | 32 | Ограничение заключается в раграничении потребностей клиентского интерфейса от потребностей сервера, хранящего 33 | данные. Данное ограничение повышает переносимость клиентского кода на другие платформы, а упрощение серверной 34 | части улучшает масштабируемость системы. 35 | 36 | ### 2. Остутствие состояния 37 | 38 | В период между запросами серверу не нужно хранить информацию о состоянии клиента и наоборот. Все запросы от клиента 39 | должны быть составлены со всей необходимой для выполнения запроса сервером информации. 40 | 41 | ### 3. Кэширование 42 | 43 | Клиенты могут выполнять кеширование ответов сервера, у которых должно быть обозначение как кэшируемых или 44 | некэшируемых для поддержания правильноти и аткуальности данных. 45 | 46 | ### 4. Единобразие интерфейса 47 | 48 | Наличие общего формата запросов для сервера и ответов для клиентов 49 | 50 | ### 5. Слои 51 | 52 | Иерархическая структура сетей с применением промежуточных серверов. Применение промежуточных серверов способно повысить 53 | масштабируемость за счёт балансировки нагрузки и распределённого кэширования. 54 | 55 | --- 56 | 57 | 58 | 59 | # Коммуникаия между клиентом и сервером 60 | 61 | Коммуникация проходит путем запросов-ответов. 62 | 63 | Запросы состоят содержат: 64 | - [HTTP метод](../Spring/mvc/README.md#HTTP); 65 | - [заголовок](https://ru.wikipedia.org/wiki/Список_заголовков_HTTP); 66 | - URI; 67 | - тело запроса - JSON или XML. 68 | 69 | 70 | 71 | ## URI и ресурсы 72 | 73 | **Ресурсы** - все то, что может иметь имя, аналоги классов в Java: пользователь, отчет, запрос, заказ, 74 | картинка, видео, анимацией, PDF. 75 | 76 | Клиенты отпраляют запросы на **эндпоинты** - аналог адреса в сети - **URI**: последовательность символов, 77 | идентифицирующая абстрактный или физический ресурс. Uniform Resource Identifier — унифицированный идентификатор ресурса. 78 | 79 | **URI** - путь до ресурса, для каждого ресурса он уникален. 80 | 81 | URI в REST начинается с множественной формы существительного, описывающего некоторый ресурс. Например, со слова 82 | clients. Далее через слэш указывают ID — идентификатор некоторого конкретного клиента. 83 | 84 | 85 | 86 | ### Примеры: 87 | ``` 88 | /clients — URI всех имеющихся клиентов; 89 | /clients/23 — URI конкретного клиента, а именно клиента с ID=23; 90 | /clients/4 — URI конкретного клиента, а именно клиента с ID=4. 91 | ``` 92 | 93 | Можно продолжить URI, добавив к нему заказы: 94 | ``` 95 | /clients/4/orders — URI всех заказов клиента №4; 96 | /clients/1/orders/12 — URI заказа №12 клиента №1. 97 | ``` 98 | 99 | Если мы продолжим эту цепочку и добавим еще и товары, получим: 100 | ``` 101 | /clients/1/orders/12/items — URI списка всех товаров в заказе №12 сделанного клиентом №1. 102 | ``` 103 | С уровнями вложенности главное — делать URI интуитивно понятными. 104 | 105 | ## Примеры запросов 106 | 107 | | Запрос | Описание | 108 | |--------|----------------------------------------------------------| 109 | |GET /clients/23
Accept : application/json, application/xml| Получить информацию о клиенте №23 в формате json или xml | 110 | |POST /clients
{
"name" : "Amigo",
"email" : "amigo@jr.com",
"phone" : "+7 (191) 746-43-23"
} | Создать нового клиента с полями:
Имя — Amigo
Email — amigo@jr.com
Тел. — +7 (191) 746-43-23| 111 | |PUT /clients/1
{
"name" : "Ben",
"email" : "bigben@jr.com",
"phone" : "+380 (190) 346-42-13"
}|Редактировать клиента №1 в следующим образом:
Имя — Ben
Email — bigben@jr.com
Тел. — +380 (190) 346-42-13| 112 | |DELETE /clients/12/orders/6|Удалить из системы заказ №6 у клиента №12| 113 | -------------------------------------------------------------------------------- /Notes/Architecture/SCRUM/SCRUM.md: -------------------------------------------------------------------------------- 1 | # SCRUM 2 | 3 | **SCRUM** - cпособ организации процесса, методик для активного решения задач. 4 | 5 | **SCRUM** - методология с конкретными правилами, создающая такую систему, которая обеспечивает результативность вашего процесса 6 | и продукта. 7 | 8 | ## Спринт 9 | 10 | **Спринт** - короткий временной интервал, в течение которого scrum-команда выполняет заданный объем работы. 11 | 12 | Спринты повышают управляемость проектов, позволяют командам поставлять высококачественные продукты быстрее и чаще, а также обеспечивают большую гибкость при адаптации к изменениям. 13 | 14 | ## Этапы планирования и выполнения Спринтов 15 | 16 | sprint lifecycle.png 17 | 18 | 1. **Планирование** - меропритие, на котором команда отвечает на два основных вопроса: какую работу можно выполнить в спринте 19 | и как она будет выполняться.
Владелец продукта/SCRUM-мастер и команда разработчиков определяют цель спринта и задачи 20 | из бэклога (**бэклог** - выбранные рабочие задачи и план по их выполнению), которые нужно выполнить для достижения поставленной цели. 21 | 2. **Ежедневный SCRUM** - в течение спринта команда собирается на ежедневные совещания(стендапы), чтобы обсудить ход 22 | работы и выявить блокеры и проблемы,которые могут повлиять на достижение цели спринта. 23 | 3. По окончании спринта команда показывает выполненную работу на **обзоре итогов спринта**. 24 | 4. **Ретроспектива спринта** - обсуждение областей, требующих улучшения в следующем спринте. С этими сведениями начинается 25 | новый цикл 26 | 27 | ## Собрания 28 | 29 | Проводятся для следующих целей: 30 | 1. Планирование спринтов (около часа на каждую неделю итерации. Спринт на 2 недели = 2 часа собрания по планированию) 31 | 2. Ежедневный стендап (15 минут) - обсуждение прогресса и выялвления блокеров. 32 | 3. Ретроспектива итерации (45 минут на каждую неделю итерации). -------------------------------------------------------------------------------- /Notes/Architecture/SCRUM/img/sprint lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Architecture/SCRUM/img/sprint lifecycle.png -------------------------------------------------------------------------------- /Notes/Databases/Configuration.md: -------------------------------------------------------------------------------- 1 | # Конфигурация БД 2 | 3 | * [Получение доступа к значениям из файла свойств](#DatabaseConfiguration) 4 | * [Использование аннотации `@Value`](#ValueAnnotation) 5 | * [Абстракция среды Spring](#BootConfiguration) 6 | 7 | --- 8 | 9 | 10 | 11 | # Получение доступа к значениям из файла свойств 12 | 13 | Файл свойств по умолчанию, создаваемый `Spring Boot`, называется `application.properties` и находится в каталоге `src/main/resources/` проекта. Свойства следуют одному и тому же синтаксису ключ=значение. При инициализации проекта файл по умолчанию пуст. 14 | 15 | Пример файла `application.properties`: 16 | 17 | ```properties 18 | db.driver=org.postgresql.Driver 19 | db.url=jdbc:postgresql://localhost:5432/data_base 20 | db.username=postgres 21 | db.password=8888 22 | ``` 23 | > Обычно файл `.properties` не публикуют (скрытый, к примеру в .gitignore). 24 | > 25 | > Можно создать публичный файл c такимже префиксом, названием и окончанием `.origin`, но без значений (ключ=). Он будет задавать структуру файла, которая нужна для запуска приложения. 26 | ____ 27 | 28 | 29 | 30 | # Использование аннотации @Value 31 | 32 | Аннотация `@Value` -это предварительно определенная аннотация, используемая для чтения значений из любых файлов свойств в пути к классам проекта. 33 | 34 | Чтобы получить доступ к значению одного свойства из файла свойств с помощью этой аннотации, указываем имя свойства в качестве аргумента: 35 | 36 | ```Java 37 | @Value("${db.driver}") 38 | private String DRIVER_DB; //org.postgresql.Driver 39 | ``` 40 | ___ 41 | 42 | 43 | # Абстракция среды Spring 44 | 45 | Другим способом доступа к значениям, определенным в `Spring Boot`, является автоматическое подключение объекта `Environment` и вызов метода `getProperty()` для доступа к значению файла свойств. 46 | 47 | Метод `getProperty()` принимает один обязательный параметр, представляющий собой строку, содержащую имя свойства, и возвращает значение этого свойства, если оно существует. Если свойство не существует, метод вернет значение **null**. 48 | 49 | ```Java 50 | @SpringBootApplication 51 | public class MvcCrudApplication implements EnvironmentAware { 52 | private String DRIVER_DB; 53 | 54 | @Override 55 | public void setEnvironment(Environment environment) { 56 | this.DRIVER_DB = environment.getProperty("db.driver"); 57 | //... 58 | } 59 | } 60 | ``` 61 | 62 | Другой вариант — просто внедрить `Environment` в наш контроллер/компонент. 63 | 64 | ```Java 65 | @SpringBootApplication 66 | public class MvcCrudApplication { 67 | 68 | @Autowired 69 | private Environment environment; 70 | 71 | public void setEnvironment() { 72 | String DRIVER_DB = environment.getProperty("db.driver"); 73 | //... 74 | } 75 | } 76 | ``` 77 | ____ 78 |
79 | -------------------------------------------------------------------------------- /Notes/Databases/Database.md: -------------------------------------------------------------------------------- 1 | # Java и базы данных 2 | 3 | ## Содержание 4 | JDBC API 5 | * [Пример создания соединения](#connection) 6 | * [Statement - создание SQL-выражений](#statement) 7 | * [PreparedStatement](#preparedStatement) 8 | * [Выполнение SQL-выражений](#execute) 9 | 10 | [JdbcTemplate](#JdbcTemplate) 11 | * [JdbcTemplateSteps](#JdbcTemplateSteps) 12 | * [RowMapper](#RowMapper) 13 | * [Выполнение запросов](#JdbcTemplateExecution) 14 | * [Batch Update | Пакетное обновление](#BatchUpdate) 15 | 16 | # JDBC API 17 | 18 | 19 | 20 | ## Создание соединения на примере HikariCP 21 | 22 | ```java 23 | HikariConfig config = new HikariConfig(); // Создание и заполнение конфига соединения 24 | config.setJdbcUrl(DB_URL); 25 | config.setUsername(DB_USERNAME); 26 | config.setPassword(DB_PASSWORD); 27 | 28 | HikariDataSource hikariDataSource = new HikariDataSource(config); // Создание пула соединений 29 | if (hikariDataSource.getConnection() == null) { 30 | throw new SQLException("Database connection failed"); 31 | } 32 | return hikariDataSource.getConnection(); // Возврат соединения типа Connection 33 | ``` 34 | 35 | 36 | 37 | ## Statement - создание SQL-выражений 38 | 39 | Для **выполнения команд** используется объект класса `Statement`. 40 | - `Statement` - базовый, предназначен для выполнения простых запросов и извлечения результатов. 41 | - `PreparedStatement`- позволяет добавлять в запросы входные параметры; добавлять методы управления входными папаметрами. 42 | - `CallableStatement` - используется для вызовов хранимых процедур; добавляет методы для манипуляции выходными параметрами. 43 | 44 | ### Пример 45 | 46 | ```java 47 | Connection connection = DriverManager.getConnection(url, username, password); 48 | Statement statement = connection.createStatement(); 49 | ``` 50 | 51 | 52 | 53 | ## Выполнение SQL-выражений 54 | 55 | - `executeQuery` - используется в запросахв запросах, результатом которых является один единственный набор значений, 56 | таких как запросов типа **SELECT**.

57 | - `executeUpdate` - следует использовать для **INSERT**, **UPDATE**, **DELETE** - результат - количество измененных 58 | строк таблицы. `CREATE TABLE`, `DROP TABLE` - возвращаемое значениие 0.

59 | - `execute` - редко используется, в случаях, когда операторы SQL возвращают более одного набора данных, более одного 60 | счетчика обновлений или и то, и другое. 61 | 62 | ### Пример 63 | ```java 64 | ResultSet resultSet = statement.executeQuery("SElECT * FROM chat.messages WHERE id = " + id); 65 | if(resultSet.next()){ 66 | long authorId=resultSet.getInt("author"); 67 | long roomId=resultSet.getInt("chatroom"); 68 | long messageId=resultSet.getInt("id"); 69 | } 70 | 71 | // Проверить, если результате выполнения запроса не нашлось ни одной строки 72 | if (!resultSet.next()) { 73 | throw new NotSavedSubEntityException(); 74 | } else { 75 | String name = resultSet.getString("name"); 76 | if (!chatroom.getName().equals(name)) { 77 | throw new NotSavedSubEntityException(); 78 | } 79 | } 80 | ``` 81 | 82 | 83 | 84 | ## Использование PreparedStatement 85 | 86 | **PreparedStatement** предварительно компилирует запросы, которые могут содержать входные параметры обозначенные символом 87 | `?`, вместо которых определяются значения. 88 | > Нумерация `?` **начинается с 1**. 89 | 90 | **Предотвращает уязвимость к SQL-инъекциям** 91 | 92 | ### Пример 93 | 94 | ```java 95 | PreparedStatement pstmt = null; 96 | //~~~ Чтение таблицы БД ~~~ 97 | pstmt = connection.prepareStatement( 98 | "SELECT * FROM GOODS where id > ? and id < ?"); 99 | // Определяем значения параметров 100 | pstmt.setInt(1, 2); 101 | pstmt.setInt(2, 10); 102 | // Выполнение запроса 103 | ResultSet rs = preparedStatement.executeQuery(); 104 | 105 | // Вывод результата запроса 106 | while (rs.next()) { 107 | System.out.println("" + rs.getRow() + ". " + 108 | "id = " + result2.getInt("id") + 109 | ", name = '" + rs.getString("name")); 110 | } 111 | //~~~ Запись в таблицу БД ~~~ 112 | pstmt = connection.prepareStatement( 113 | "INSERT INTO GOODS(name) values(?)"); 114 | pstmt.setString(1, "Кофе"); 115 | pstmt.executeUpdate(); 116 | ``` 117 | 118 | --- 119 | 120 |
121 | 122 | 123 | 124 | # Jdbc Template 125 | 126 | Зависимость `Notes.Spring jdbc` 127 | 128 | Обертка вокруг JDBC API, которая предоставляется Notes.Spring Framework 129 | 130 | 1. Сокращает код за счет отсутствия создания `Connection`, `Statement`, работы с `ResultSet`. 131 | 2. Предотвращает дублирование кода 132 | 3. Отсутствие неинформативного `SQLException` 133 | 134 | 135 | 136 | ## Алгоритм работы с JdbcTemplate 137 | 138 | ### 1. Создать бин для DataSource и JdbcTemplate 139 | ```java 140 | @Bean 141 | public DataSource dataSource() { 142 | DriverManagerDataSource dataSource = new DriverManagerDataSource(); 143 | 144 | dataSource.setDriverClassName("org.postgresql.Driver"); 145 | dataSource.setUrl("jdbc:postgresql://localhost:5432/springcourse"); 146 | dataSource.setUsername("postgres"); 147 | dataSource.setPassword("1234"); 148 | 149 | return dataSource; 150 | } 151 | 152 | @Bean 153 | public JdbcTemplate jdbcTemplate() { 154 | return new JdbcTemplate(dataSource()); 155 | } 156 | ``` 157 | 158 | ### 2. Добавить поле и соответствующий конструктор в DAO-класс 159 | Спринг внедрит зависимость с помощью аннотации `@Autowired`. 160 | ```java 161 | private JdbcTemplate jdbcTemplate; 162 | 163 | @Autowired 164 | public PersonDAO(JdbcTemplate jdbcTemplate) { 165 | this.jdbcTemplate = jdbcTemplate; 166 | } 167 | ``` 168 | 169 | 170 | 171 | ### 3. Создать RowMapper 172 | **RowMapper** - объект, отображающий строки результата запроса в POJO-объекты указанного класса. 173 | 174 | ```java 175 | public class PersonMapper implements RowMapper { 176 | @Override 177 | public Person mapRow(ResultSet rs, int rowNum) throws SQLException { 178 | Person person = new Person(); 179 | person.setId(rs.getInt("id")); 180 | person.setName(rs.getString("name")); 181 | person.setEmail(rs.getString("email")); 182 | person.setAge(rs.getInt("age")); 183 | 184 | return person; 185 | } 186 | } 187 | ``` 188 | Класс реализовывает интерфейс RowMapper. Создаем новый объект, помещаем значения из `resultSet`. 189 | 190 | #### BeanPropertyRowMapper 191 | В случае совпадения имени поля и имени ячейки таблицы можно использовать BeanPropertyRowMapper. 192 | ```java 193 | ```java 194 | public List index() { 195 | return jdbcTemplate.query("SELECT * FROM Person", new BeanPropertyRowMapper<>(Person.class)); 196 | } 197 | ``` 198 | 199 | 200 | 201 | ### 4. Выполнение запроса 202 | 203 | **Показать всех пользователей из таблицы.** 204 | 205 | ```java 206 | public List index() { 207 | return jdbcTemplate.query("SELECT * FROM Person", new PersonMapper()); 208 | } 209 | ``` 210 |
211 | 212 | **Показать пользователя c конкретным id.** 213 | 214 | `new Object[]{id}` - массив значений, которые должны быть подставлены вместо `?` в `preparedStatement`. 215 | (в данном примере - это id). 216 | 217 | ```java 218 | public Person show(int id) { 219 | return jdbcTemplate.query("SELECT * FROM Person WHERE id=?", new Object[]{id}, new PersonMapper()) 220 | .stream().findAny().orElse(null); 221 | } 222 | ``` 223 | 224 | **Сохранение пользователя** 225 | 226 | ```java 227 | public void save(Person person) { 228 | jdbcTemplate.update("INSERT INTO Person(name, age, email) VALUES(?, ?, ?)", person.getName(), person.getAge(), person.getEmail()); 229 | } 230 | ``` 231 | 232 | **Обновить пользователя** 233 | ```java 234 | public void update(int id, Person updatedPerson) { 235 | jdbcTemplate.update("UPDATE Person SET name=?, age=?, email=? WHERE id=?", updatedPerson.getName(), updatedPerson.getAge(), 236 | updatedPerson.getEmail(), id); 237 | } 238 | ``` 239 | 240 | **Удалить пользователя** 241 | ```java 242 | public void delete(int id) { 243 | jdbcTemplate.update("DELETE FROM Person WHERE id=?", id); 244 | } 245 | ``` 246 | 247 | 248 | 249 | ## Batch Update | Пакетное обновление 250 | 251 | Механизм упаковки множества записей в пакет и отправка его в БД. 252 | 253 | Снижает нагрузку на бд за счет отправки множества запросов и получения ответов на них 254 | в виде одного пакета. БД может распараллеливать оперции вставки на несколько потоков. 255 | 256 | ```java 257 | jdbcTemplate.batchUpdate("INSERT INTO person(name, age, email) VALUES (?, ?, ?)", 258 | new BatchPreparedStatementSetter() { 259 | @Override 260 | public void setValues(PreparedStatement preparedStatement, int i) throws SQLException { 261 | preparedStatement.setString(1, people.get(i).getName()); 262 | preparedStatement.setInt(2, people.get(i).getAge()); 263 | preparedStatement.setString(3, people.get(i).getEmail()); 264 | } 265 | 266 | @Override 267 | public int getBatchSize() { 268 | return people.size(); 269 | } 270 | }); 271 | ``` 272 | 273 | 274 | -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/1_databases.md: -------------------------------------------------------------------------------- 1 | # Основные команды PSQL 2 | ***Смена кодировки*** 3 | ``` 4 | \! chcp 1251 5 | \set PROMPT1 %n@%/%R%# 6 | \set PROMPT2 :PROMPT1 7 | ``` 8 | 9 |
10 | 11 | `\?` - полный список команд psql 12 | 13 | `\h КОМАНДА` - справка по SQL-оператору, без имени - по всем 14 | 15 | `\i ИМЯ_ФАЙЛА` - импортировать БД 16 | 17 |
18 | 19 | # Операции с БД 20 | 21 | `CREATE DATABASE test;` - создание новой БД 22 | 23 | `DROP DATABASE имя;` - удалить БД 24 | 25 | `\l` - все доступные БД 26 | 27 | `\c test` - переключение на БД 28 | 29 |
-------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/2.1_CREATE_TABLE.md: -------------------------------------------------------------------------------- 1 | # Операции с таблицами 2 | 3 | `\dt` - Список таблиц 4 | 5 | `\d НАЗВАНИЕ` - информация о таблице 6 | 7 | `ALTER TABLE старое_название RENAME TO новое_название;` - переименовывание таблицы 8 | 9 |
10 | 11 | # Создание таблицы 12 | 13 | ``` 14 | CREATE TABLE название 15 | ( 16 | Имя поля тип(макс кол-во символов для ввода) [ограничения], 17 | Имя поля тип(макс кол-во символов для ввода) [ограничения], 18 | ... 19 | Имя поля тип(макс кол-во символов для ввода) [ограничения], 20 | [ограничения], 21 | [первичный ключ], 22 | [внешний ключ] 23 | ); 24 | ``` 25 | **PRIMARY KEY** - обязательное поле 26 | 27 | Пример 28 | 29 | ``` 30 | CREATE TABLE movies 31 | ( 32 | id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, // счетчик 33 | name CHARACTER VARYING(30) NOT NULL, 34 | price numeric(5, 2) 35 | ); 36 | ``` 37 | 38 | Для **MySQL** автоидексация имеет синтаксис `AUTO_INCREMENT` 39 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 | 58 | # Ограничения 59 | Добавление ограничения 60 | ``` 61 | ALTER TABLE название_таблицы ADD CHECK (name <> ''); 62 | ALTER TABLE название_таблицы ADD CONSTRAINT some_name UNIQUE (столбец); 63 | ALTER TABLE название_таблицы ADD FOREIGN KEY (product_group_id) 64 | REFERENCES product_groups; 65 | ``` 66 | `CHECK` - проверка условия, например (price > 0) 67 | 68 | `CONSTRAINT` - присвоение ограничению отдельного имени, используется для вывода сообщений об ошибках и позволяет ссылаться на это имя при изменении ограничения (Пример: **CONSTRAINT positive_price CHECK (price > 0)**) 69 | 70 | `UNIQUE` - уникальный параметр (имена в строках не повторяются) 71 | 72 |
73 | 74 | Чтобы **добавить ограничение NOT NULL**, которое нельзя записать в виде ограничения таблицы: 75 | ``` 76 | ALTER TABLE products ALTER COLUMN столбец SET NOT NULL; 77 | ``` 78 | Удаление ограничения 79 | ``` 80 | ALTER TABLE таблица DROP CONSTRAINT ограничение; 81 | ``` 82 | Удаление ограничения NOT NULL 83 | ``` 84 | ALTER TABLE таблица ALTER COLUMN столбец DROP NOT NULL; 85 | ``` 86 | Назначить столбцу новое значение по умолчанию 87 | ``` 88 | ALTER TABLE название_таблицы ALTER COLUMN столбец SET DEFAULT 7.77; 89 | ``` 90 | Удалить значение по умолчанию 91 | ``` 92 | ALTER TABLE название_таблицы ALTER COLUMN столбец DROP DEFAULT; 93 | ``` 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
110 | 111 | # Создание таблицы на основе данных из другой таблицы 112 | Синтаксис: 113 | ``` 114 | CREATE TABLE имя_таблицы AS 115 | SELECT ... 116 | ``` 117 | ***Пример:*** Создать таблицу заказ (ordering), куда включить авторов и названия тех книг, количество экземпляров которых в таблице book меньше 4. Для всех книг указать одинаковое количество экземпляров 5. 118 | ``` 119 | CREATE TABLE ordering AS 120 | SELECT author, title, 5 AS amount 121 | FROM book 122 | WHERE amount < 4; 123 | 124 | SELECT * FROM ordering; 125 | ``` -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/2.2_TABLES_INSERT_DELETE_UPDATE_ALTER.md: -------------------------------------------------------------------------------- 1 | # Столбцы | ALTER 2 | Добавление нового столбца 3 | ``` 4 | ALTER TABLE Название_таблицы 5 | ADD Название_столбца Тип(макс кол-во символов для ввода) [ограничения]; 6 | ``` 7 | Удаление столбца 8 | ``` 9 | ALTER TABLE products DROP COLUMN название; 10 | ``` 11 | Переименование столбца 12 | ``` 13 | ALTER TABLE products RENAME COLUMN старое_название TO новое_название; 14 | ``` 15 | Изменение типа данных столбца 16 | ``` 17 | ALTER TABLE название_таблицы ALTER COLUMN стобец TYPE тип(макс кол-во символов для ввода); 18 | ``` 19 | 20 | 21 |
22 | 23 | # Добавить строку | INSERT INTO 24 | Добавить строку в таблицу 25 | ``` 26 | INSERT INTO Название_таблицы 27 | (через_запятую_поля_которые_требуется_изменить) 28 | VALUES (значения_полей), 29 | (значения_полей), 30 | (значения_полей); 31 | ``` 32 | Текстовые значение вводятся в одинарных ковычках (Пример: \`значение\`) 33 | 34 |
35 | 36 | ## Добавление записей из другой таблицы 37 | 38 | С помощью запроса на добавление можно не только добавить в таблицу конкретные значения (список **VALUES**), но и записи из другой таблицы, отобранные с помощью запроса на выборку. В этом случае вместо раздела **VALUES** записывается запрос на выборку, начинающийся с **SELECT**. В нем можно использовать **WHERE**, **GROUP** **BY**, **ORDER BY** 39 | ``` 40 | INSERT INTO book (title, author, price, amount) 41 | SELECT title, author, price, amount 42 | FROM supply; 43 | 44 | SELECT * FROM book; 45 | ``` 46 | 47 |
48 | 49 | ## Добавление записей, вложенные запросы 50 | **Пример:** Занести из таблицы supply в таблицу book только те книги, авторов которых нет в book. 51 | 52 | ``` 53 | INSERT INTO book 54 | (title, author, price, amount) 55 | SELECT title, author, price, amount FROM supply 56 | WHERE author NOT IN (SELECT author FROM book); 57 | ``` 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | 67 | # Обновить данные | UPDATE 68 | ``` 69 | UPDATE Название_таблицы 70 | SET price = 10 71 | WHERE критерий строки; 72 | ``` 73 | Пример: **UPDATE products SET price = 10 WHERE price = 5;** - увеличивает цену всех товаров, имевших до этого цену 5, до 10 74 | 75 |
76 | 77 | ## Запросы на обновление нескольких столбцов 78 | Синтаксис 79 | ``` 80 | UPDATE таблица SET поле1 = выражение1, поле2 = выражение2 81 | ``` 82 | **Пример:** 83 | ``` 84 | UPDATE book 85 | SET amount = amount - buy, 86 | buy = 0; 87 | ``` 88 | 89 |
90 | 91 | ## Обновление нескольких таблиц 92 | В запросах на обновление можно использовать несколько таблиц, но тогда 93 | 94 | - для столбцов, имеющих одинаковые имена, необходимо указывать имя таблицы, к которой они относятся, например, **book.price** – столбец **price** из таблицы **book**, **supply.price** – столбец **price** из таблицы **supply**; 95 | - все таблицы, используемые в запросе, нужно перечислить после ключевого слова **UPDATE**; 96 | - в запросе обязательно условие **WHERE**, в котором указывается условие при котором обновляются данные. 97 | 98 | **Пример**: Если в таблице supply есть те же книги, что и в таблице book, добавлять эти книги в таблицу book не имеет смысла. Необходимо увеличить их количество на значение столбца amountтаблицы supply. 99 | ``` 100 | UPDATE book, supply 101 | SET book.amount = book.amount + supply.amount 102 | WHERE book.title = supply.title AND book.author = supply.author; 103 | ``` 104 |
105 | 106 | # Удаление строк из таблицы | DELETE 107 | Синтаксис: 108 | ``` 109 | DELETE FROM таблица 110 | WHERE условие; 111 | ``` 112 | `DELETE FROM таблица;` - удалить все записи из таблицы 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 124 | # Источники 125 | 126 | 127 | https://postgrespro.ru/docs/postgresql/9.6/ddl-alter#ddl-alter-removing-a-column 128 | 129 | https://postgrespro.ru/docs/postgrespro/9.5/ddl-constraints 130 | -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/3_field_types.md: -------------------------------------------------------------------------------- 1 | # Типы данных 2 | ## I. Целочисленные 3 | - smallint 4 | - integer 5 | - bigint 6 | 7 | Автоматическая нумерация `integer primary key generated always as identity` 8 | 9 | ### C фиксированной точностью знаков 10 | - numeric 11 | - decimal. 12 | 13 | Используются для точных вычислений, имеют общий синтаксис 14 | ``` 15 | numeric(кол-во цифр в числе, кол-во цифр после запятой) 16 | 17 | decimal(кол-во цифр в числе, кол-во цифр после запятой) 18 | ``` 19 | ### С плавающей точкой 20 | - real 21 | - double 22 | - float 23 | 24 |
25 | 26 | --- 27 | ## II. Символьные 28 | 29 | - character(n) - `char` - дополняет до n пробелами 30 | - character varying(n) - `varchar` - не дополняет 31 | - `text` - не имеет ограничений 32 | 33 | Параметр n отвечает за макс. количество символов в поле 34 | 35 |
36 | 37 | --- 38 | 39 | ## III. Типы "дата/время" 40 | - date(yyyy-mm-dd) 41 | ``` 42 | SELECT 'Sep 12, 2016'::date; 43 | ``` 44 | ``` 45 | SELECT '21:15:(опционально секунды)'::time; 46 | ``` 47 | Для вычитания двух дат используется функция DATEDIFF(дата_1, дата_2), результатом которой является количество дней между дата_1 и дата_2. 48 | Для того, чтобы выделить номер месяца из даты используется функция MONTH(дата). 49 | 50 | Например, MONTH('2020-04-12') = 4. 51 | 52 | Если определяется месяц для значений столбца date_first, то используется запись MONTH(date_first) 53 | 54 | Для того, чтобы выделить название месяца из даты используется функция MONTHNAME(дата), которая возвращает название месяца на английском языке для указанной даты. Например, MONTHNAME('2020-04-12')='April' 55 | **DATEDIFF(начало; конец)** 56 | 57 | --- 58 | 59 |
60 | 61 | ## IV. Логический тип boolean 62 | - Истина: TRUE, 't','true', 'y', 'yes', 'on', '1'. 63 | - Ложь: FALSE, 'f', 'false', 'n', 'no', 'off', '0'. 64 | 65 | --- 66 | 67 |
68 | 69 | ## V. Массивы 70 | 71 | Для объявления массива к имени типа нужно добавить квадртные скобки, указывать число элементов не обязательно. 72 | 73 | `schedule integer[]` - пример объявления 74 | 75 | `{1, 2, 3, 4, 5, 6}` - присвоение значения 76 | 77 |
78 | 79 | ### Основные операции 80 | 81 | Добавление значения с помощью `конкатенации` 82 | ``` 83 | UPDATE pilots 84 | SET schedule = schedule || 7 85 | WHERE pilot_name = 'Boris'; 86 | ``` 87 | 88 |
89 | 90 | Добавление значения в конец списка с помощью ф-ии `array_append` 91 | 92 | ``` 93 | UPDATE pilots 94 | SET schedule = array_prepend( 1, schedule ) 95 | WHERE pilot_name = 'Pavel'; 96 | ``` 97 | 98 |
99 | 100 | Добавление значения в конец списка с помощью ф-ии `array_prepend` 101 | 102 | ``` 103 | UPDATE pilots 104 | SET schedule = array_prepend( 1, schedule ) 105 | WHERE pilot_name = 'Pavel'; 106 | ``` 107 | 108 |
109 | 110 | Удаление элемента массива с помощью ф-ии `array_remove` 111 | 112 | ``` 113 | UPDATE pilots 114 | SET schedule = array_remove( schedule, 5 ) 115 | WHERE pilot_name = 'Ivan'; 116 | ``` 117 | 118 |
119 | 120 | Обащение к элементам массива `по индексам` 121 | 122 | ``` 123 | UPDATE pilots 124 | SET schedule[ 1 ] = 2, schedule[ 2 ] = 3 125 | WHERE pilot_name = 'Petr'; 126 | ``` 127 | --- 128 | 129 |
130 | 131 | ## VI. JSON 132 | 133 | Существует 2 типа - json и `jsonb`, различющиеся в основном, в быстродействии 134 | 135 | json - быстрая вставка строк, медленное последующее обращение, сохраняет порядок следования ключей. jsonb противоположен. 136 | 137 | ``` 138 | CREATE TABLE pilot_hobbies 139 | ( 140 | pilot_name text, 141 | hobbies jsonb 142 | ); 143 | 144 | INSERT INTO pilot_hobbies 145 | VALUES ( 'Ivan', 146 | '{ "sports": [ "ôóòáîë", "ïëàâàíèå" ], 147 | "home_lib": true, "trips": 3 148 | }'::jsonb 149 | ), 150 | ( 'Petr', 151 | '{ "sports": [ "òåííèñ", "ïëàâàíèå" ], 152 | "home_lib": true, "trips": 2 153 | }'::jsonb 154 | ), 155 | ( 'Pavel', 156 | '{ "sports": [ "ïëàâàíèå" ], 157 | "home_lib": false, "trips": 4 158 | }'::jsonb 159 | ), 160 | ( 'Boris', 161 | '{ "sports": [ "ôóòáîë", "ïëàâàíèå", "òåííèñ" ], 162 | "home_lib": true, "trips": 0 163 | }'::jsonb 164 | ); 165 | ``` 166 | -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/4.0_queries.md: -------------------------------------------------------------------------------- 1 | # Запросы 2 | Порядок команд: 3 | + SELECT 4 | + CASE 5 | + FROM 6 | + WHERE 7 | + ORDER BY 8 | + LIMIT 9 | + OFFSET 10 | 11 | # Основные команды 12 | `SELECT` - Список SELECT (между ключевыми словами SELECT и FROM) 13 | 14 | `SELECT DISCTINCT` - неповторяющиеся значения 15 | 16 | `FROM` - перечисляются одна или несколько таблиц, служащих источниками данных для SELECT 17 | 18 | `LIMIT число` - ограничить число строк в выборке 19 | 20 | `OFFSET число` - пропустить строки в выборке. OFFSET 4 - пропуск 4 строк, запрос выводит строки, начиная с 5. 21 | 22 | # Принадлежность 23 | 24 | `столбец AS столбец` - присвоение имени столбцу 25 | 26 | **SELECT name AS first** - переименовывание столбца 27 | 28 | **SELECT range, range/1.609 AS miles** - первый столбец км, второй - мили 29 | 30 | `ORDER BY столбец` - сортирует значения по столбцу. ORDER BY столбец DESC; - сортировка по убыванию 31 | 32 |
33 | 34 | ## Условие выражения 35 | ``` 36 | CASE WHEN условие THEN выражение 37 | [ WHEN ... ] 38 | [ ELSE выражение ] 39 | END 40 | ``` 41 | Пример 42 | ``` 43 | SELECT model, range, 44 | CASE WHEN range < 2000 THEN 'Ближнемагистральный' 45 | WHEN range < 5000 THEN 'Среднемагистральный' 46 | ELSE 'Дальнемагистральный' 47 | END AS type 48 | FROM aircrafts 49 | ORDER BY model; 50 | ``` 51 | IF(условие, выражение, иначе) 52 | 53 | # Источики 54 | 55 | https://postgrespro.ru/docs/postgresql/9.6/sql-select 56 | 57 | https://postgrespro.ru/docs/postgresql/9.6/functions-matching -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/4.1_WHERE_querries.md: -------------------------------------------------------------------------------- 1 | # Операторы WHERE 2 | `WHERE условие` - условие, выдающее результат типа boolean 3 | 4 |
5 | 6 | # LIKE 7 | `LIKE шаблон` - возвращает true, если строка соответствует заданному шаблону. (для `NOT LIKE шаблон` - не соответствует) 8 | 9 | Если ***шаблон*** не содержит *знак*ов процента и подчёркиваний, тогда шаблон представляет в точности строку и LIKE работает как оператор сравнения. 10 | 11 | ***Подчёркивание (_)*** в шаблоне подменяет (вместо него подходит) любой символ; а ***знак процента (%)*** подменяет любую (в том числе и пустую) последовательность символов. 12 | 13 | ***Пример: SELECT * FROM aircrafts WHERE model LIKE 'Airbus%';*** 14 | 15 | ***Пример: SELECT * FROM airports WHERE airport_name LIKE '___';*** 16 | 17 | `ILIKE` не заботится о регистрах. 18 |
19 | 20 | # SIMILAR TO 21 | `SIMILAR TO условие` работает как LIKE, является более современным аналогом 22 | 23 |
24 | 25 | # POSIX 26 | Регулярные выражения POSIX предоставляют более мощные средства поиска по шаблонам, чем операторы LIKE и SIMILAR TO. 27 | 28 | `~` - ищет совпадения с шаблоном с учетом регистра 29 | 30 | `~*` - ищет совпадения с шаблоном без учета регистра 31 | 32 | `!~` - проверяет несовпадение с шаблоном с учетом регистра 33 | 34 | `!~*` - проверяет несовпадение с шаблоном без учета регистра 35 | 36 |
37 | 38 | `^` - поиск совпадения будет привязан к началу строки 39 | 40 | `$` - поиск совпадения будет привязан к началу строки SELECT * FROM aircrafts WHERE model !~ '300$'; 41 | 42 | `(значение | значение | ...)` - альтернативный выбор между несколькими значниями 43 | 44 | SELECT * FROM aircrafts WHERE model ~ '^(A|Boe)'; - значения, начинающиеся либо на 'A', либо на 'Boe' 45 | 46 |
47 | 48 | # Выборка данных, операторы BETWEEN, IN 49 | Оператор BETWEEN позволяет отобрать данные, относящиеся к некоторому интервалу, включая его границы. 50 | 51 | *Пример*: Выбрать названия и количества тех книг, количество которых от 5 до 14 включительно. 52 | 53 | Запрос 54 | ``` 55 | SELECT title, amount 56 | FROM book 57 | WHERE amount BETWEEN 5 AND 14; 58 | ``` 59 | Оператор IN позволяет выбрать данные, соответствующие значениям из списка. 60 | 61 | *Пример*: Выбрать названия и цены книг, написанных Булгаковым или Достоевским. 62 | ``` 63 | SELECT title, price 64 | FROM book 65 | WHERE author IN ('Булгаков М.А.', 'Достоевский Ф.М.'); 66 | ``` -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/4.2_GROUP_querries.md: -------------------------------------------------------------------------------- 1 | # Агрегирование и группировка 2 | 3 | Агрегирование позволяет в одной строке результат размещать значение, вычисленные по нескольким строкам и таблицам. 4 | 5 | Виды ф-ий: count, avg, sum. min, max. 6 | 7 | `GROUP BY элемент_группирования [, ...]` - собирает в одну строку все выбранные строки, выдающие одинаковые значения для выражений группировки 8 | 9 | 1. В таблице определяются строки, в которых в выбранном столбце одинаковые значения. Получаем различные группы. 10 | 11 | 2. Вместо каждой группы в результирующий запрос включается одна запись. Запись как минимум включает значение столбца, по которому осуществляется группировка 12 | 13 | 3. Дальше можно выполнить вычисления над элементами КАЖДОЙ группы в отдельности, например, посчитать общее количество экземпляров книг каждого автора. Для этого используется групповая функция ***SUM()***, а в скобках указывается столбец, по которому нужно выполнить суммирование 14 | 15 | Также можно посчитать, сколько записей относится к группе. Для этого используется функция ***COUNT()***, в скобках можно указать ЛЮБОЙ столбец из группы, если группа не содержит пустых значений (ниже приведен пример, в котором показано, как работает COUNT(), если в группе есть пустые значения); 16 | 17 | В качестве аргумента групповых функций SQL может использоваться не только столбец, но и любое допустимое в SQL арифметическое выражение. 18 | 19 | **Пример:** вывести суммарную стоимость книг каждого автора. 20 | ``` 21 | SELECT author, SUM(price * amount) AS Стоимость 22 | FROM book 23 | GROUP BY author; 24 | 25 | +------------------+-----------+---------+-------------------+ 26 | | author | Стоимость | НДС | Стоимость_без_НДС | 27 | +------------------+-----------+---------+-------------------+ 28 | | Булгаков М.А. | 4715.47 | 719.31 | 3996.16 | 29 | | Достоевский Ф.М. | 11802.03 | 1800.31 | 10001.72 | 30 | | Есенин С.А. | 9750.00 | 1487.29 | 8262.71 | 31 | +------------------+-----------+---------+-------------------+ 32 | ``` 33 |
34 | 35 | # Вычисления по таблице целиком 36 | 37 | Групповые функции позволяют вычислять итоговые значения по всей таблице. Например, можно посчитать общее количество книг на складе, вычислить суммарную стоимость и пр. Для этого после ключевого слова SELECT указывается групповая функция для выражения или имени столбца, а ключевые слова GROUP BY опускаются. 38 | 39 | **Пример:** Вывести цену самой дешевой книги, цену самой дорогой и среднюю цену уникальных книг на складе. Названия столбцов Минимальная_цена, Максимальная_цена, Средняя_цена соответственно. Среднюю цену округлить до двух знаков после запятой. 40 | 41 | ``` 42 | SELECT 43 | MIN(price) AS 'Минимальная_цена', 44 | MAX(price) AS 'Максимальная_цена', 45 | ROUND(AVG(price),2) AS 'Средняя_цена' 46 | FROM book; 47 | 48 | +------------------+-------------------+--------------+ 49 | | Минимальная_цена | Максимальная_цена | Средняя_цена | 50 | +------------------+-------------------+--------------+ 51 | | 460.00 | 799.01 | 600.17 | 52 | +------------------+-------------------+--------------+ 53 | ``` 54 |
55 | 56 | # HAVING 57 | 58 | В запросы с групповыми функциями можно включать условие отбора строк, которое в обычных запросах записывается после **WHERE**. В запросах с групповыми функциями вместо **WHERE** используется ключевое слово **HAVING** , которое размещается после оператора **GROUP BY**. 59 | 60 | **Пример:** Найти минимальную и максимальную цену книг всех авторов, общая стоимость книг которых больше 5000. 61 | 62 | ``` 63 | SELECT author, 64 | MIN(price) AS Минимальная_цена, 65 | MAX(price) AS Максимальная_цена 66 | FROM book 67 | GROUP BY author 68 | HAVING SUM(price * amount) > 5000; 69 | 70 | +------------------+------------------+-------------------+ 71 | | author | Минимальная_цена | Максимальная_цена | 72 | +------------------+------------------+-------------------+ 73 | | Достоевский Ф.М. | 460.00 | 799.01 | 74 | | Есенин С.А. | 650.00 | 650.00 | 75 | +------------------+------------------+-------------------+ 76 | ``` 77 | 78 |
79 | 80 | # Группировка по нескольким столбцам 81 | 82 | В разделе GROUP BY можно указывать несколько столбцов, разделяя их запятыми. Тогда к одной группе будут относиться записи, у которых значения столбцов, входящих в группу, равны. Рассмотрим группировку по нескольким столбцам на примере следующего запроса: 83 | ``` 84 | SELECT name, number_plate, violation, count(*) 85 | FROM fine 86 | GROUP BY name, number_plate, violation; 87 | ``` 88 | 1. Сначала записи таблицы **fine** разделяются на группы. В каждую группу включаются строки, у которых равны значения в столбцах **name**, **number_plate** и **violation** соответственно. Получается 6 групп. 89 | 90 | 2. Затем вычисляется функция count(*), которая определяет количество записей в каждой группе. Получается, что к первым двум группам относятся по две записи, ко всем остальным - по одной. 91 | 92 | **Важно!** В разделе GROUP BY нужно перечислять все НЕАГРЕГИРОВАННЫЕ столбцы (к которым не применяются групповые функции) из SELECT. -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/4.3_nested_querries.md: -------------------------------------------------------------------------------- 1 | # Вложенные запросы 2 | 3 | **Вложенный запрос** используется для выборки данных, которые будут использоваться в условии отбора записей основного запроса. Его применяют для 4 | 5 | **Пример: Вывести информацию о самых дешевых книгах, хранящихся на складе** 6 | 7 | Для реализации этого запроса нам необходимо получить минимальную цену из столбца price таблицы book, а затем вывести информацию о тех книгах, цена которых равна минимальной. Первая часть – поиск минимума – реализуется вложенным запросом. 8 | ``` 9 | SELECT title, author, price, amount 10 | FROM book 11 | WHERE price = ( 12 | SELECT MIN(price) 13 | FROM book 14 | ); 15 | 16 | +-------+------------------+--------+--------+ 17 | | title | author | price | amount | 18 | +-------+------------------+--------+--------+ 19 | | Идиот | Достоевский Ф.М. | 460.00 | 10 | 20 | +-------+------------------+--------+--------+ 21 | ``` 22 | Вложенный запрос определяет минимальную цену книг во всей таблице (это 460.00), а затем в основном запросе для каждой записи проверяется, равна ли цена минимальному значению, если равна, информация о книге включается в результирующую таблицу запроса. 23 | 24 |
25 | 26 | # Оператор IN 27 | Оператор **IN** определяет, совпадает ли указанное в логическом выражении значение с одним из значений, содержащихся во вложенном запросе , при этом логическое выражение получает значение истина. Оператор **NOT** **IN** выполняет обратное действие – выражение истинно, если значение не содержится во вложенном запросе. 28 | 29 |
30 | 31 | # Операторы ANY и ALL 32 | ## ANY 33 | `amount > ANY (число_1, число_2)` - больше минимального 34 | 35 | `amount < ANY (число_1, число_2)` - меньше максимального 36 | 37 | `amount = ANY (число_1, число_2)` эквивалентно `amount IN (10,12)` 38 | 39 | `amount <> ANY (10, 12)` вернет все записи с любым значением **amount**, включая **число_1** и **число_2** 40 | 41 | ## ALL 42 | `amount > ALL (число_1, число_2)` - больше максимального 43 | 44 | `amount < ALL (число_1, число_2)` - меньше минимального 45 | 46 | `amount = ALL (число_1, число_2)` не вернет ни одной записи, так как эквивалентно `(amount = число_1) AND (amount = число_2)` 47 | 48 | `amount <> ALL (число_1, число_2)` вернет все записи кроме тех, в которых **amount** равно **число_1** или **число_2** 49 | 50 | **Важно!** Операторы `ALL` и `ANY` можно использовать только с вложенными запросами. В примерах выше (число_1, число_2) приводится как результат вложенного запроса просто для того, чтобы показать как эти операторы работают. В запросах так записывать нельзя. 51 | 52 |
53 | 54 | # Вложенный запрос после SELECT 55 | 56 | Вложенный запрос может располагаться после ключевого слова SELECT. В этом случае результат выполнения запроса выводится в отдельном столбце результирующей таблицы. При этом результатом запроса может быть только одно значение, тогда оно будет повторяться во всех строках. Также вложенный запрос может использоваться в выражениях. 57 | 58 |
59 | 60 | **Пример:** Посчитать сколько и каких экземпляров книг нужно заказать поставщикам, чтобы на складе стало одинаковое количество экземпляров каждой книги, равное значению самого большего количества экземпляров одной книги на складе. Вывести название книги, ее автора, текущее количество экземпляров на складе и количество заказываемых экземпляров книг. Последнему столбцу присвоить имя Заказ. В результат не включать книги, которые заказывать не нужно. 61 | ``` 62 | +---------+-----------------------+------------------+--------+--------+ 63 | | book_id | title | author | price | amount | 64 | +---------+-----------------------+------------------+--------+--------+ 65 | | 1 | Мастер и Маргарита | Булгаков М.А. | 670.99 | 3 | 66 | | 2 | Белая гвардия | Булгаков М.А. | 540.50 | 5 | 67 | | 3 | Идиот | Достоевский Ф.М. | 460.00 | 10 | 68 | | 4 | Братья Карамазовы | Достоевский Ф.М. | 799.01 | 3 | 69 | | 5 | Игрок | Достоевский Ф.М. | 480.50 | 10 | 70 | | 6 | Стихотворения и поэмы | Есенин С.А. | 650.00 | 15 | 71 | +---------+-----------------------+------------------+--------+--------+ 72 | ``` 73 | Решение 74 | ``` 75 | SElECT title, author, amount,(SELECT MAX(amount) FROM book) - amount AS Заказ 76 | FROM book 77 | WHERE (SELECT MAX(amount) FROM book) - amount > 0; 78 | 79 | +--------------------+------------------+--------+-------+ 80 | | title | author | amount | Заказ | 81 | +--------------------+------------------+--------+-------+ 82 | | Мастер и Маргарита | Булгаков М.А. | 3 | 12 | 83 | | Белая гвардия | Булгаков М.А. | 5 | 10 | 84 | | Идиот | Достоевский Ф.М. | 10 | 5 | 85 | | Братья Карамазовы | Достоевский Ф.М. | 3 | 12 | 86 | | Игрок | Достоевский Ф.М. | 10 | 5 | 87 | +--------------------+------------------+--------+-------+ 88 | ``` -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/6_user_access.md: -------------------------------------------------------------------------------- 1 | # Управление доступом в БД 2 | Текущие пользователи `SELECT session_user;` 3 | 4 | Просмотр привиллегий `\z` 5 | 6 | Создание роли: `CREATE ROLE имя` 7 | 8 | Удаление роли: `DROP ROLE имя;` 9 | 10 | Существующие роли: `\du` или `\du роль` 11 | 12 | Предоставление привилений: `GRANT привилегия ON объект_данных TO пользователь;` 13 | 14 | Использование роли для создания сеансов: `ALTER ROLE роль LOGIN;` | `\password пользователь` 15 | 16 | 17 | Привилегии: 18 | - SELECT 19 | - UPDATE 20 | - INSERT 21 | - DELETE 22 | - TRUNCATE (разрешение на усечение таблицы) 23 | 24 | - REFERENCE (работа с ссылками (FOREIGN KEY)) 25 | 26 | - TRIGGER (работа с триггерами для таблчных объектов) 27 | 28 | - TEMPORARY (позволяет создавать временную таблицу при подключении к установленной базе данных) 29 | 30 | - EXECUTE (позволяет пользователю вызывать функции или процедуры) 31 | 32 | - CONNECT (подключаться к укаанной БД) 33 | 34 | - USAGE (позволяет создавать функции на заданном языке) 35 | - ALL PRIVILEGES 36 | 37 | **Пример:** `GRANT SELECT ON TABLE airports TO public; 38 | GRANT` - предоставление право выборки из таблицы всем пользователям сервера 39 | 40 | Отозвать привилегию: 'REVOKE привилегия ON объект_данных FROM пользователь;' 41 | -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/7.0_links.md: -------------------------------------------------------------------------------- 1 | # Один ко многим 2 | Связь **«один ко многим»** имеет место, когда **одной** записи **главной** таблицы соответствует **несколько записей связанной таблицы**, а каждой записи связанной таблицы соответствует только одна запись главной таблицы. Обозначается это так: 3 | ``` 4 | |Главная| 5 | | 6 | v 7 | |Связанная (подчиненная)| 8 | ``` 9 | 10 |
11 | 12 | # Многие ко многим 13 | Связь **«многие ко многим»** имеет место когда каждой записи одной таблицы соответствует несколько записей во второй, и наоборот, каждой записи второй таблицы соответствует несколько записей в первой. Обозначается это так: 14 | ``` 15 | |Таблица| <-> |Таблица| 16 | ``` 17 |
18 | 19 | # Создание таблицы с внешними ключами 20 | При создании зависимой таблицы (таблицы, которая содержит внешние ключи) необходимо учитывать, что : 21 | 22 | - каждый внешний ключ должен иметь такой же тип данных, как связанное поле главной таблицы; 23 | 24 | - необходимо указать главную для нее таблицу и столбец, по которому осуществляется связь: 25 | ``` 26 | FOREIGN KEY (связанное_поле_зависимой_таблицы) 27 | REFERENCES главная_таблица (связанное_поле_главной_таблицы) 28 | ``` 29 | Пример: 30 | ``` 31 | CREATE TABLE book 32 | ( 33 | book_id INT PRIMARY KEY AUTO_INCREMENT, 34 | title VARCHAR(50), 35 | author_id INT NOT NULL, 36 | genre_id INT, 37 | price DECIMAL(8,2), 38 | amount INT, 39 | FOREIGN KEY (author_id) REFERENCES author (author_id), 40 | FOREIGN KEY (genre_id) REFERENCES genre (genre_id) 41 | ); 42 | 43 | SHOW COLUMNS FROM book; 44 | ``` 45 |
46 | 47 | # Действия при удалении записи главной таблицы 48 | С помощью выражения **ON DELETE** можно установить действия, которые выполняются для записей подчиненной таблицы при удалении связанной строки из главной таблицы. При удалении можно установить следующие опции: 49 | 50 | - **CASCADE**: автоматически удаляет строки из зависимой таблицы при удалении связанных строк в главной таблице. 51 | - **SET NULL**: при удалении связанной строки из главной таблицы устанавливает для столбца внешнего ключа значение NULL. (В этом случае столбец внешнего ключа должен поддерживать установку NULL). 52 | - **SET DEFAULT** похоже на SET NULL за тем исключением, что значение внешнего ключа устанавливается не в NULL, а в значение по умолчанию для данного столбца. 53 | - **RESTRICT**: отклоняет удаление строк в главной таблице при наличии связанных строк в зависимой таблице. 54 | 55 | **Важно!** Если для столбца установлена опция SET NULL, то при его описании нельзя задать ограничение на пустое значение. 56 | 57 | **Пример:** Будем считать, что при удалении автора из таблицы author, необходимо удалить все записи о книгах из таблицы book, написанные этим автором. 58 | ``` 59 | CREATE TABLE book ( 60 | book_id INT PRIMARY KEY AUTO_INCREMENT, 61 | title VARCHAR(50), 62 | author_id INT NOT NULL, 63 | price DECIMAL(8,2), 64 | amount INT, 65 | FOREIGN KEY (author_id) REFERENCES author (author_id) ON DELETE CASCADE 66 | ); 67 | ``` -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/7.1_JOIN.md: -------------------------------------------------------------------------------- 1 | # INNER JOIN 2 | Соединяет записи, для которых нашлись пары 3 | 4 | Синтаксис 5 | ``` 6 | SELECT 7 | ... 8 | FROM 9 | таблица_1 INNER JOIN таблица_2 10 | ON условие 11 | ... 12 | ``` 13 | 14 |
15 | 16 | ## LEFT JOIN 17 | Все записи первой таблицы, для ненайденных пар из второй поставит значения NULL 18 | 19 |
20 | 21 | ## RIGHT JOIN 22 | Все записи второй таблицы, для ненайденных пар из первой поставит значения NULL 23 | 24 |
25 | 26 | ## OUTER / FULL / CROSS JOIN 27 | Выводит все записи из обеих таблиц 28 | 29 |
30 | 31 | # USING 32 | **USING** позволяет указать набор столбцов, которые есть в обеих объединяемых таблицах. Если база данных хорошо спроектирована, а каждый внешний ключ имеет такое же имя, как и соответствующий первичный ключ (например, **genre.genre_id** = **book.genre_id**), тогда можно использовать предложение **USING** для реализации операции **JOIN**. 33 | 34 | При этом после **SELECT**, при использовании столбцов из **USING**(), необязательно указывать, из какой именно таблицы берется столбец. 35 | 36 | **Пример**: Вывести название книг, фамилии и id их авторов. 37 | 38 | Запрос: 39 | 40 | Вариант с ON 41 | ``` 42 | SELECT title, name_author, author.author_id /* явно указать таблицу - обязательно */ 43 | FROM 44 | author INNER JOIN book 45 | ON author.author_id = book.author_id; 46 | ``` 47 | Вариант с USING 48 | ``` 49 | SELECT title, name_author, author_id /* имя таблицы, из которой берется author_id, указывать не обязательно*/ 50 | FROM 51 | author INNER JOIN book 52 | USING(author_id); 53 | ``` 54 | -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/7.2_querries_multiple_tables.md: -------------------------------------------------------------------------------- 1 | # Запросы на выборку из нескольких таблиц 2 | Пример: 3 | ``` 4 | Структура: 5 | 6 | |first| 7 | | 8 | v 9 | |second| 10 | | 11 | V 12 | |third| 13 | ``` 14 | Запрос: 15 | ``` 16 | SELECT 17 | ... 18 | FROM 19 | first 20 | INNER JOIN second ON first.first_id = second.first_id 21 | INNER JOIN third ON second.second_id = third.second_id 22 | ... 23 | ``` 24 | Пример: 25 | ``` 26 | Структура: 27 | 28 | | first | | second | 29 | | | 30 | v v 31 | | third | 32 | ``` 33 | Запрос: 34 | ``` 35 | SELECT 36 | ... 37 | FROM 38 | first 39 | INNER JOIN third ON first.first_id = third.first_id 40 | INNER JOIN second ON third.second_id = second.second_id 41 | ... 42 | ``` -------------------------------------------------------------------------------- /Notes/Databases/postgreSQL/perfomance.md: -------------------------------------------------------------------------------- 1 | EXPLAIN SELECT * 2 | FROM aircrafts; 3 | 4 | Отключение параметров события 5 | 6 | EXPLAIN ( COSTS OFF ) SELECT * 7 | FROM aircrafts; 8 | 9 | -------------------------------------------------------------------------------- /Notes/Docker/examples/docker-compose-app/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine 2 | 3 | WORKDIR /app 4 | 5 | RUN pip install pymongo 6 | 7 | COPY . . 8 | 9 | CMD ["python", "main.py"] -------------------------------------------------------------------------------- /Notes/Docker/examples/docker-compose-app/app/main.py: -------------------------------------------------------------------------------- 1 | from pymongo import MongoClient 2 | from pprint import pprint 3 | 4 | MONGO_URL = "mongodb://mongo:27017" 5 | client = MongoClient(MONGO_URL) 6 | db = client.admin 7 | dbs_list = db.command("listDatabases") 8 | pprint(dbs_list) 9 | -------------------------------------------------------------------------------- /Notes/Docker/examples/docker-compose-app/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | app: 5 | build: ./app 6 | mongo: 7 | image: mongo -------------------------------------------------------------------------------- /Notes/Docker/examples/node-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | WORKDIR /app 4 | 5 | COPY . . 6 | 7 | CMD ["node", "index.mjs"] -------------------------------------------------------------------------------- /Notes/Docker/examples/node-app/index.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | 3 | fs.appendFile('my-file.txt', 'Файл создан Node.js', (err) => { 4 | if (err) throw err 5 | console.log('Файл сохранен!') 6 | }) 7 | 8 | setTimeout(()=> console.log('End!'), 10000) -------------------------------------------------------------------------------- /Notes/Docker/img/busybox1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Docker/img/busybox1.png -------------------------------------------------------------------------------- /Notes/Docker/img/busybox2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Docker/img/busybox2.png -------------------------------------------------------------------------------- /Notes/FlyWay/README.md: -------------------------------------------------------------------------------- 1 | # Миграции БД | FlyWay 2 | 3 | **Миграции** — аналог системы контроля версий для базы данных. Они позволяют изменять структуру БД так, 4 | чтобы все ее пользователи оставались в курсе изменений других участников. 5 | 6 | Зависимость 7 | ```java 8 | 9 | org.flywaydb 10 | flyway-core 11 | 9.16.3 12 | 13 | ``` 14 | 15 | Плагин для настройки подключения 16 | ``` 17 | 18 | org.flywaydb 19 | flyway-maven-plugin 20 | 7.14.0 21 | 22 | jdbc:postgresql://localhost:5432/clients 23 | postgres 24 | postgres 25 | 26 | 27 | ``` 28 | 29 | ## Maven Plugins 30 | 31 | 32 | 33 | - `baseline`: обновить информацию о миграциях 34 | - `migrate`: произвести миграцию 35 | 36 | ## Начальная точка для миграций 37 | 1. `flywat:baseline` 38 | 39 | 40 | 2. Application properties: 41 | ``` 42 | spring.jpa.show-sql = true 43 | spring.jpa.hibernate.ddl-auto = create 44 | ``` 45 | 3. Создаем файл resources/db.migration/V1__название_файла.sql 46 | 4. Копируем HIBERNATE код создания таблицы 47 | 5. Application properties: 48 | ``` 49 | spring.jpa.hibernate.ddl-auto = validate 50 | ``` 51 | 52 | ## Дальнейшие миграции 53 | 1. `flyaway:migrate` 54 | 2. Новая версия файла Vверсия__название.sql -------------------------------------------------------------------------------- /Notes/FlyWay/img/plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/FlyWay/img/plugins.png -------------------------------------------------------------------------------- /Notes/FlyWay/img/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/FlyWay/img/start.png -------------------------------------------------------------------------------- /Notes/Hibernate/HIbernateCourse.md: -------------------------------------------------------------------------------- 1 | ### Встраиваемые таблицы | Переиспользование полей 2 | 3 | Если несколько сущностей имеют общий набор полей 4 | ```java 5 | public class Employee { 6 | // ... 7 | private String companyCode; 8 | private Grade grade; 9 | // поля повторяются с классом Client 10 | private String address; 11 | private String phoneNumber; 12 | // ... 13 | } 14 | ``` 15 | ```java 16 | public class Client { 17 | // ... 18 | private boolean isFavoriteClient; 19 | // поля повторяются с классом Employee 20 | private String address; 21 | private String phoneNumber; 22 | // ... 23 | } 24 | ``` 25 | 26 | То имеет смысл вынести общие поля и методы в отдельный класс. 27 | 28 | ```java 29 | @Embeddable 30 | public class Contact { 31 | // эти поля присутствуют и в Client, и в Employee 32 | private String address; 33 | private String phoneNumber; 34 | } 35 | ``` 36 | Для общего класса НЕ БУДЕТ создаваться отдельная таблица, но поля этого класса будут добавлены 37 | к полям сущности, в которую этот класс инжектируется; 38 | 39 | ```java 40 | public class Employee { 41 | // ... 42 | private String companyCode; 43 | private Grade grade; 44 | 45 | // отдельная таблица не создается, в БД вместо этого поля будут поля класса Contact, т.е. 46 | // private String address; 47 | // private String phoneNumber; 48 | private Contact contact; 49 | // ... 50 | } 51 | ``` 52 | ```java 53 | public class Client { 54 | // ... 55 | private boolean isFavoriteClient; 56 | 57 | // отдельная таблица не создается, в БД вместо этого поля будут поля класса Contact, т.е. 58 | // private String address; 59 | // private String phoneNumber; 60 | private Contact contact; 61 | // ... 62 | } 63 | ``` 64 | 65 | Таблица employers 66 | ![img.png](img/img.png) 67 | 68 | --- 69 | 70 | ### Поле-коллекция в сущности @Entity 71 | 72 | Хранить коллекции можно следующим способом 73 | 74 | ```java 75 | @ElementCollection // обязательная аннотация для коллекций 76 | @CollectionTable(name = "employers_skills", joinColumns = @JoinColumn(name = "employee_id")) // Коллекция будет храниться в отдельной таблице "employers_skills", связь "One-to-Many" осуществляется по полю "employee_id" 77 | @Column(name = "skill") // переименовываем название столбца в связанной таблице 78 | private List skills = new ArrayList<>(); 79 | ``` 80 | 81 | Использование Map в качестве структуры для хранения данных 82 | ```java 83 | @ElementCollection // обязательная аннотация для коллекций 84 | @CollectionTable(name = "employers_skills", joinColumns = @JoinColumn(name = "employee_id")) // Коллекция будет храниться в отдельной таблице "employers_skills", связь "One-to-Many" осуществляется по полю "employee_id" 85 | @MapKeyColumn(name = "skill") // задаем имя столбца для ключа Map 86 | @Column(name = "age") // задаем имя столбца для значения Map 87 | private Map skills2Years = new HasMap<>(); 88 | ``` 89 | 90 | --- 91 | 92 | ### Создание индексов 93 | 94 | ```java 95 | @Entity 96 | @Table( 97 | name = "employees", 98 | indexes = { 99 | @Index(name = "name_index", columnList = "name"), 100 | @Index(name = "age_phone_number_index", columnList = "age, phone_number", unique = true) 101 | } 102 | ) 103 | public class Employee { 104 | // ... 105 | private String name; 106 | private Integer age; 107 | @Column(name = "phone_number") 108 | private String phoneNumber; 109 | // ... 110 | } 111 | ``` 112 | 113 | 114 | -------------------------------------------------------------------------------- /Notes/Hibernate/HibernateQuerries.md: -------------------------------------------------------------------------------- 1 | Поле 2 | ```java 3 | @PersistenceContext 4 | private EntityManager entityManager; 5 | ``` 6 | 7 | Метод 8 | ```java 9 | @Override 10 | @SuppressWarnings("unchecked") 11 | public List findActiveTasks() { 12 | if (entityManager == null || entityManager.unwrap(Session.class) == null) { 13 | throw new NullPointerException(); 14 | } 15 | return entityManager.createQuery("select task from Task task where task.status = ?1").setParameter(1, "ACTIVE").getResultList(); 16 | } 17 | ``` -------------------------------------------------------------------------------- /Notes/Hibernate/JPACriteriaQueries.md: -------------------------------------------------------------------------------- 1 | ```java 2 | @Id 3 | @SequenceGenerator(name = "_id_seq", sequenceName = "_id_seq", allocationSize = 1) 4 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "_id_seq") 5 | private Long id; 6 | ``` -------------------------------------------------------------------------------- /Notes/Hibernate/img/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/img.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/manyToMany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/manyToMany.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/manyToOne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/manyToOne.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/manyToOneJava.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/manyToOneJava.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/mtmBi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/mtmBi.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/mtmMapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/mtmMapping.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/mtmUni.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/mtmUni.png -------------------------------------------------------------------------------- /Notes/Hibernate/img/otmBi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Hibernate/img/otmBi.png -------------------------------------------------------------------------------- /Notes/Java/Collection/Program.java: -------------------------------------------------------------------------------- 1 | package Notes.Java.Collection; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Program { 7 | private static void displayMap(Map map) { 8 | System.out.println("Map" + map); 9 | for (Map.Entry element : map.entrySet()) { 10 | Integer key = element.getKey(); 11 | String value = element.getValue(); 12 | System.out.println("Ключ: " + key + "\tЗначение: " + value); 13 | } 14 | 15 | } 16 | 17 | public static void main(String[] args) { 18 | Map map = new HashMap<>(); 19 | map.put(1, "one"); 20 | map.put(2, "two"); 21 | 22 | 23 | 24 | displayMap(map); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Notes/Java/Collection/README.md: -------------------------------------------------------------------------------- 1 | # Коллекции и структуры данных 2 | ## Содержание 3 | 4 | * [Map](#map) 5 | * [HashMap](#hashmap) 6 | * [LinkedHashMap](#linkedmap) 7 | * [TreeMap](#treemap) 8 | * [HashTable](#hashtable) 9 |

10 | * [Set](#set) 11 | * [HashSet](#hashset) 12 | * [LinkedHashSet](#linkedhashset) 13 | * [TreeSet](#treeset) 14 | * [EnumSet](#enumset) 15 |

16 | * [Enum](#enum) 17 | * [ArrayList](#arraylist) 18 | 19 | --- 20 | 21 | 22 | 23 | # Enum | Перечисления 24 | 25 | Представляют набор логически связанных констант. Объявление перечисления происходит 26 | с помощью оператора enum, после которого идет название перечисления. 27 | Затем идет список элементов перечисления через запятую: 28 | 29 | ```java 30 | enum Day{ 31 | 32 | MONDAY, 33 | TUESDAY, 34 | WEDNESDAY, 35 | THURSDAY, 36 | FRIDAY, 37 | SATURDAY, 38 | SUNDAY 39 | } 40 | ``` 41 | ### Конструкторы, поля и методы перечисления 42 | Перечисления, как и обычные классы, могут определять конструкторы, поля и методы. 43 | Позволяет создавать константы с полями. 44 | ```java 45 | enum Color{ 46 | RED("#FF0000"), BLUE("#0000FF"), GREEN("#00FF00"); 47 | private String code; 48 | Color(String code){ 49 | this.code = code; 50 | } 51 | public String getCode(){ return code;} 52 | } 53 | ``` 54 | 55 | --- 56 | 57 | 58 | 59 | ## ArrayList 60 | 61 | ### Конструкторы 62 | ```java 63 | ArrayList()// создает пустой список 64 | ArrayList(Collection col)// создает список, в который добавляются все элементы коллекции col. 65 | ``` 66 | ### Основные методы 67 | 68 | * `void add(int index, E obj)`// добавляет в список по индексу index объект obj 69 | * `boolean addAll(int index, Collection col)` // добавляет в список по индексу index все элементы коллекции col. Если в результате добавления список был изменен, то возвращается true, иначе возвращается false 70 | * `E get(int index)` // возвращает объект из списка по индексу index 71 | * `int indexOf(Object obj)` // возвращает индекс первого вхождения объекта obj в список. Если объект не найден, то возвращается -1 72 | * `E remove(int index)` // удаляет объект из списка по индексу index, возвращая при этом удаленный объект 73 | * `E set(int index, E obj)` // присваивает значение объекта obj элементу, который находится по индексу index 74 | * `void sort(Comparator comp)` // сортирует список с помощью компаратора comp 75 | * `List subList(int start, int end)` // получает набор элементов, которые находятся в списке между индексами start и end 76 | 77 | --- 78 | 79 | 80 | 81 | # Map | Словарь 82 | 83 | Интерфейс Map содержит основные реализации: `Hashmap`, `LinkedHashMap`, `Hashtable`, `TreeMap`. 84 | 85 | 86 | 87 | ## HashMap 88 | 89 | Коллекция "ключ-значение", все ключи уникальны в рамках объекта **Program**. 90 | 91 | > Облегчает поиск значения, если известен ключ - уникальный итендификатор. 92 | 93 | ### Создание словаря. Заполнение и получение значений 94 | ```java 95 | HashMap hashMap = new HashMap<>(); 96 | hashMap.put(1, "one"); // добавление элемента, если в коллекции уже есть элемент с подобным ключом, то он перезаписывается 97 | hashMap.put(2, "two"); 98 | hashMap.put(3, "three"); 99 | hashMap.get(1); // Получение значения по ключу или null, если значение отсутствует 100 | hashMap.get(2); 101 | hashMap.get(3); 102 | ``` 103 | ### Перебор словаря и вывод содержимого на экран 104 | ```java 105 | for (Map.Entry entry : hashMap.entrySet()) // entrySet() - возвращает множество элементов коллекции 106 | { 107 | System.out.print("key: " + entry.getKey()); // getKey() - получить ключ сущности 108 | System.out.println("; value: " + entry.getValue()); // getKey() - получить значение сущности 109 | } 110 | ``` 111 | 112 | ### Конвертация Map в List 113 | ```java 114 | // key list 115 | List keyList = new ArrayList<>(map.keySet()); 116 | // value list 117 | List valueList = new ArrayList<>(map.values()); 118 | // key-value list 119 | List> entryList = new ArrayList<>(map.entrySet()); 120 | ``` 121 | 122 | ### Счетчик ключей Map 123 | 124 | ```java 125 | //map 126 | while ((line = bufferedReader.readLine()) != null) { 127 | String[] words = line.split("\\W"); { 128 | for (String word : words) { 129 | if (word.equals("")) { 130 | continue; 131 | } 132 | if (!map.containsKey(word)) { 133 | map.put(word, 1); 134 | } else { 135 | map.put(word, map.get(word) + 1); 136 | } 137 | } 138 | } 139 | } 140 | ``` 141 | 142 | 143 | ### Основные методы 144 | 145 | ```java 146 | void clear() // очищает коллекцию 147 | int size() // возвращает количество элементов коллекции 148 | boolean containsKey(Object k) // возвращает true, если коллекция содержит ключ k 149 | boolean containsValue(Object v) // возвращает true, если коллекция содержит значение v 150 | int size() // возвращает количество элементов коллекции 151 | replace(ключ, значение); // заменить значение элемента по ключу 152 | remove(ключ); // удаление элемента по ключу 153 | ``` 154 | 155 | 156 | ## LinkedHashMap 157 | 158 | **LinkedHashMap** - отображение с запоминанием порядка, в котором добавлялись элементы, разрешает перебор в порядке вставки. 159 | 160 | ```java 161 | // ====LinkedHashMap==== 162 | System.out.println("LinkedHashMap"); 163 | LinkedHashMap linkedHashMap = new LinkedHashMap<>(); 164 | linkedHashMap.put(1, "one"); 165 | linkedHashMap.put(3, "three"); 166 | linkedHashMap.put(4, "four"); 167 | linkedHashMap.put(2, "two"); 168 | for (Map.Entry entry : linkedHashMap.entrySet()) { 169 | System.out.println("key: " + entry.getKey() + "; value = " + entry.getValue()); 170 | } 171 | 172 | // ====HashMap==== 173 | System.out.println("\nHashMap"); 174 | HashMap hashMap = new HashMap<>(); 175 | hashMap.put(1, "one"); 176 | hashMap.put(3, "three"); 177 | hashMap.put(4, "four"); 178 | hashMap.put(2, "two"); 179 | for (Map.Entry entry : hashMap.entrySet()) { 180 | System.out.println("key: " + entry.getKey() + "; value = " + entry.getValue()); 181 | } 182 | 183 | // Результат 184 | LinkedHashMap 185 | key: 1; value = one 186 | key: 3; value = three 187 | key: 4; value = four 188 | key: 2; value = two 189 | 190 | HashMap 191 | key: 1; value = one 192 | key: 2; value = two 193 | key: 3; value = three 194 | key: 4; value = four 195 | ``` 196 | 197 | 198 | 199 | ## TreeMap 200 | 201 | `Map` сортирующая элементы по ключу. Позволяет как создавать изначально отсортированные мапы или 202 | сортировать уже существующие. 203 | 204 | ### Сортировка ключей существующей `Map` 205 | 206 | ```java 207 | LinkedHashMap linkedHashMap = new LinkedHashMap<>(); // неотсортированная мапа 208 | linkedHashMap.put("xxx", 5); 209 | linkedHashMap.put("a", 3); 210 | linkedHashMap.put("ccc", 1); 211 | linkedHashMap.put("b", 2); 212 | for (Map.Entry entry : linkedHashMap.entrySet()) { 213 | System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue()); 214 | } 215 | 216 | System.out.println("\n"); 217 | 218 | TreeMap treeMap = new TreeMap<>(linkedHashMap); // Передача неотсортированной мапы для сортировки 219 | for (Map.Entry entry : treeMap.entrySet()) { 220 | System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue()); 221 | } 222 | 223 | //Результат 224 | key: xxx; value: 5 225 | key: a; value: 3 226 | key: ccc; value: 1 227 | key: b; value: 2 228 | 229 | key: a; value: 3 230 | key: b; value: 2 231 | key: ccc; value: 1 232 | key: xxx; value: 5 233 | ``` 234 | 235 | 236 | 237 | ## HashTable 238 | 239 | HashTable хранит пары ключей/значений в хэш-таблице. В качестве ключа выступает хэш-код переданного объекта, который используется 240 | как индекс. 241 | 242 | --- 243 | # Set | Множества 244 | 245 | 246 | 247 | > Каждый элемент хранится только в одном экземпляре, разные реализации `Set` используют разный порядок хранения 248 | элементов. 249 | 250 | Если порядок хранения важен, применяется `TreeSet`, в котором **объекты хранятся отсортированными по возрастанию** 251 | или `LinkedHashSet`. с **хранением элементов в порядке добавления**. 252 | 253 | 254 | 255 | ## HashSet 256 | 257 | ### Создание множества и заполнение элементами 258 | ```java 259 | HashSet countries = new HashSet<>(); // Создание множества 260 | countries.add("Россия"); // добавление элемента в множенство 261 | countries.add("Франция"); // если такого элемента нет 262 | countries.add("Испания"); // возвр. true - если добавился элемент иначе false 263 | ``` 264 | 265 | ### Получение множества | метод `iterator()` 266 | **iterator()** - метод позволяющий получить все множество элементов. 267 | ```java 268 | Iterator iterator = countries.iterator(); // Создание итератора 269 | while (iterator.hasNext()) { 270 | System.out.println(iterator.next()); 271 | } 272 | ``` 273 | 274 | ### Основные методы 275 | 276 | ```java 277 | int size() // размер 278 | boolean isEmpty() 279 | boolean contains(Object o) 280 | boolean addAll(Collection c) 281 | Object[] toArray() 282 | boolean remove(Object o) 283 | boolean removeAll(Collection c) 284 | void clear() 285 | ``` 286 | 287 | 288 | 289 | ## LinkedHashSet | Элементы в порядке добавления 290 | 291 | Не добавляет новых методов. ласс поддерживает связный список элементов набора в том порядке, в котором они вставлялись. 292 | Это позволяет организовать упорядоченную итерацию вставки в набор. 293 | 294 | 295 | 296 | ## TreeSet | Элементы отсортированные по возрастанию 297 | 298 | ```java 299 | Random random = new Random(); 300 | SortedSet sortedNumbers = new TreeSet<>(); //Создаие TreeSet 301 | 302 | for (int i = 0; i < 5; i++) { 303 | sortedNumbers.add(random.nextInt(10)); 304 | } 305 | 306 | // Результаты работы 307 | Элементы отсортированы по возрастанию, размер множества меняется, так как повторяющиеся 308 | элементы не добавляются, а игнорируются 309 | [0, 4, 6, 9] 310 | [0, 1, 2, 4, 8] 311 | [2, 3, 9] 312 | ``` 313 | 314 | 315 | 316 | ## EnumSet 317 | Содержит только значения перечисления, принадлежащие к тому же типу перечисления, элементы хранятся в порядке 318 | их сохранения. Он не позволяет пользователю добавлять значения `NULL` и создает исключение `NullPointerException`. 319 | 320 | --- 321 | -------------------------------------------------------------------------------- /Notes/Java/Java8/streamApi/StreamApi.md: -------------------------------------------------------------------------------- 1 | # Stream API 2 | 3 | Используются для обработки потока данных с помощью цепочки методов. 4 | 5 | **Поток (Stream)**: Поток представляет последовательность элементов данных. Он не хранит данные, а лишь обрабатывает их на лету при выполнении операций. 6 | 7 | ### Преимущества Stream 8 | 9 | - благодаря стримам **больше не нужно писать стереотипный код** каждый раз, когда приходится что-то делать с данными: сортировать, фильтровать, преобразовывать. Разработчики меньше думают о стандартной реализации и больше времени уделяют более сложным вещам; 10 |

11 | - методы Stream API **не изменяют исходные коллекции**, уменьшая количество побочных эффектов. 12 |

13 | - Распараллеливать проведений операций с коллекциями стало проще. Там, где раньше пришлось бы проходить циклом, **стримы значительно сокращают количество кода**. 14 | 15 | # Основные методы 16 | 17 | Выделяют два основных типов методов: 18 | 19 | - **конвейерные**: операции применяются к потоку и возвращают новый поток. Они выполняются лениво, что означает, что они не изменяют исходный поток данных, а создают новый поток с примененными операциями. 20 | - **терминальные**: применяются к потоку и возвращают результат. Они являются триггером для выполнения всех промежуточных операций и завершения обработки данных в потоке. 21 | 22 | 23 | ### filter(Predicate predicate) - фильтр 24 | Фильтрует элементы потока согласно условию, заданному предикатом. 25 | 26 | Пример: 27 | Список пользователей, имя которых содержит "М" 28 | ```java 29 | userList.stream().filter(user -> user.getFirstName().contains("M")).collect(Collectors.toSet()).forEach(System.out::println); 30 | ``` 31 | 32 |
33 | 34 | ### map(Function mapper) - преобразование элементов 35 | Применяет функцию к каждому элементу потока и возвращает новый поток с преобразованными значениями. 36 | 37 | Пример: создание списка из id-пользователей 38 | ```java 39 | List ids = userList.stream().map(User::getId).map(Long::intValue).collect(Collectors.toList()); 40 | ids.forEach(System.out::println); 41 | ``` 42 | Пример: получение нового списка пользователей с измененными полями 43 | ```java 44 | userList.stream().map(user -> new User(user.getId(), "X", "Y", 0, "XY")).forEach(System.out::println); 45 | ``` 46 | 47 | Пример: замены имени пользователя 48 | ```java 49 | userList.stream().map(user -> { 50 | if (user.getFirstName().equals("Michael")) { 51 | return new User(user.getId(), "Nikita", user.getLastName(), user.getAge(), user.getNationality()); 52 | } 53 | return user; 54 | }).forEach(System.out::println); 55 | ``` 56 | 57 |
58 | 59 | ### flatMap() - плоский список 60 | 61 | Применение flatMap позволяет объединить несколько потоков в один и получить плоский список элементов. 62 | Таким образом, flatMap часто применяется, когда у нас есть вложенные коллекции или списки, и мы хотим получить 63 | один плоский список всех элементов. 64 | 65 | Пример: есть список из объектов Person, и каждый Person имеет список его друзей. Необходимо получить список всех друзей 66 | из всех Person. 67 | 68 | ```java 69 | public class Person { 70 | private String name; 71 | private List friends; 72 | 73 | // Конструктор и геттеры 74 | 75 | public static void main(String[] args) { 76 | List persons = List.of( 77 | new Person("Alice", List.of(new Person("Bob"), new Person("Charlie"))), 78 | new Person("David", List.of(new Person("Eve"), new Person("Frank"))) 79 | ); 80 | 81 | List allFriends = persons.stream() 82 | .flatMap(person -> person.getFriends().stream()) 83 | .toList(); 84 | 85 | allFriends.forEach(friend -> System.out.println(friend.getName())); 86 | } 87 | } 88 | 89 | ``` 90 | 91 |
92 | 93 | ### sorted(Comparator comparator) - сортировка 94 | Сортирует элементы потока в соответствии с компаратором 95 | 96 | Пример: **сортировка по возрастанию** 97 | ```java 98 | userList.stream().sorted(Comparator.comparingInt(User::getAge)) 99 | ``` 100 | 101 | Пример: **сортировка по убыванию** 102 | ```java 103 | userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()) 104 | ``` 105 | 106 | Пример: **множественная сортировка** 107 | ```java 108 | userList.stream().sorted(Comparator.comparing(User::getLastName).thenComparing(User::getFirstName)) 109 | ``` 110 |
111 | 112 | ### min, max, average, count, sum 113 | Предоставляет удобный способ получения статистической информации о числовом потоке, такой как количество элементов, сумму, минимальное и максимальное значение, среднее значение и т.д. 114 | 115 | Пример: 116 | ```java 117 | List ages = userList.stream().map(User::getAge).toList(); 118 | int minimalAge = ages.stream().min(Integer::compare).orElse(Integer.MAX_VALUE); 119 | int maximalAge = ages.stream().max(Integer::compare).orElse(Integer.MIN_VALUE); 120 | double averageAge = ages.stream().mapToInt(Integer::intValue).average().orElse(0); 121 | int sum = ages.stream().mapToInt(Integer::intValue).sum(); 122 | long count = ages.stream().count(); 123 | ``` 124 | 125 |
126 | 127 | ### allMatch, anyMatch 128 | 129 | Проверяют соответстиве элементов соответственно предикату. 130 | 131 | Пример: проверка на то, что возраст всех пользователей больше 76 132 | ```java 133 | boolean isAllAgesGreaterThan76 = userList.stream().allMatch(user -> user.getAge() > 76); 134 | ``` 135 | 136 | Пример: проверка на то, что возраст хотя бы одного пользователя больше 76 137 | ```java 138 | boolean isAnyAgesGreaterThan76 = userList.stream().anyMatch(user -> user.getAge() > 76); 139 | ``` 140 | 141 | 142 | ## Примеры 143 | 144 | ### Вычисление максимальной длины firstname 145 | 146 | ```java 147 | int maxFirstnameLength = userList.stream().mapToInt(user -> user.getFirstName().length()).summaryStatistics().getMax(); 148 | ``` 149 | 150 | ### Конвертация коллекций 151 | 152 | ```java 153 | Set userSet = userList.stream().collect(Collectors.toSet()); 154 | LinkedList userLinkedList = userList.stream().collect(Collectors.toCollection(LinkedList::new)); 155 | Map userMap = userList.stream().collect(Collectors.toMap(user -> user.getId(), user -> user)); 156 | ``` -------------------------------------------------------------------------------- /Notes/Java/OOP.md: -------------------------------------------------------------------------------- 1 | # ООП 2 | 3 | Программа считается объектно-ориентированной, только если выполнены **все три требования**: 4 | - ООП использует в качестве основных логических конструктивных элементов объекты, а не алгоритмы; 5 | - каждый объект является экземпляром определенного класса 6 | - классы образуют иерархии 7 | 8 | ООП **обязательно должно использовать** наследование, в противном случае методология будет не объектно-ориентированной, а **программированием с помощью абстрактных типов данных**. 9 | 10 | > Согласно парадигме ООП программа состоит из объектов, обменивающихся сообщениями. Объекты могут обладать состоянием, единственный способ изменить состояние объекта - послать ему сообщение, в ответ на которое объект может изменить свое состояние. 11 | 12 | **Класс** – это способ описания сущности, определяющий состояние и поведение, зависящее от этого состояния, а также правила для взаимодействия с данной сущностью (контракт). 13 | 14 | >С точки зрения программирования класс можно рассматривать как набор данных (полей, атрибутов, членов класса) и функций для работы с ними (методов). 15 | > 16 | >С точки зрения структуры программы, класс является сложным типом данных. 17 | 18 | **Объект** (экземпляр) – это отдельный представитель класса, имеющий конкретное состояние и поведение, полностью определяемое классом. Каждый объект имеет конкретные значения атрибутов и методы, работающие с этими значениями на основе правил, заданных в классе. 19 | 20 | **Интерфейс** – это набор методов класса, доступных для использования. Интерфейсом класса будет являться набор всех его публичных методов в совокупности с набором публичных атрибутов. По сути, интерфейс специфицирует класс, чётко определяя все возможные действия над ним. 21 | 22 | 23 | 24 | ## Преимущества и недостатки ООП 25 | 26 | **Преимущества**: 27 | - Ориентированность на человеческое восприятие мира, а не на компьютерную реализацию; 28 | - Классы позволяют абстрагироваться от деталей реализации; 29 | - Локализация кода и данных улучшает наглядность и удобство сопровождения программного обеспечения. 30 | Локализация кода заключается в объединении данных и методов для работы с ними в единую 31 | сущность, не разнося их по всей программе как в случае с процедурным программированием. 32 | - Возможности описать независимые от приложения части предметной области в виде набора универсальных классов, или фреймворка, который в дальнейшем будет расширен за счет добавления частей, специфичных для конкретного приложения. 33 | - Повторное использование кода: 34 | - Сокращение времени на разработку; 35 | - Сокращение количества ошибок; 36 | - Упрощение использования, понимания и написания кода. 37 | 38 | **Недостатки**: 39 | - Документирование классов - задача более трудная, чем это было в случае процедур и модулей. Поскольку любой метод может быть переопределен, в документации должно говориться не только о том, что делает данный метод, но и о том, в каком контексте он вызывается. 40 | - Неэффективность и неэкономное распределения памяти на этапе выполнения (по причине издержек на динамическое связывание и проверки типов на этапе выполнения). 41 | - Излишняя универсальность. Часто содержится больше методов, чем это реально необходимо текущей программе. А поскольку лишние методы не могут быть удалены, они становятся мертвым грузом. 42 | 43 | 44 | 45 | ## Статическое и динамическое связывание 46 | 47 | Присоединение вызова метода к телу метода называется **связыванием**. 48 | Если связывание проводится компилятором (компоновщиком) перед запуском программы, то оно называется **статическим или ранним связыванием (early binding).** 49 | 50 | **Позднее связывание (late binding), динамическим (dynamic) или связыванием на стадии выполнения (runtime binding)** - это связывание, проводимое непосредственно во время выполнения программы, в зависимости от типа объекта. 51 | В языках, реализующих позднее связывание, должен существовать механизм определения фактического типа объекта во время работы программы, для вызова подходящего метода. 52 | Иначе говоря, компилятор не знает тип объекта, но механизм вызова методов определяет его и вызывает соответствующее тело метода. Механизм позднего связывания зависит от конкретного языка, но нетрудно предположить, что для его реализации в объекты должна включаться какая-то дополнительная информация. 53 | 54 | > Для всех методов Java используется механизм позднего (динамического) связывания, если только метод не был объявлен как `final` (приватные методы являются `final` по умолчанию). 55 | 56 | 57 | 58 | ## Инкапсуляция 59 | 60 | **Инкапсуляция** - механизм языка, связывающий данные и методы для работы с ними в единый объект, позволяющий реализовать сокрытие. 61 | 62 | **Цель инкапсуляции** - уйти от зависимости внешнего интерфейса класса (то, что могут использовать другие классы) от реализации. Малейшее изменение в классе не должно влечь за собой изменение внешнего поведения класса. 63 | 64 | ### Реализация сокрытия 65 | 66 | - Модификаторы доступа (private, public, protected, package-private или friendly) 67 | - Ключевое слово `package`, разделяющее глобальное пространство имен (package mypackage;) 68 | - Ключевое слово `import`, подключающее пакет (import java.util.ArrayList; import mypackage;) 69 | 70 | Отличие `private` от `friendly`: 71 | - **private** - никто не имеет доступа к члену кроме класса, в котором он объявлен, а также вложенных и внешних классов. **не наследуются**'. 72 | - **friendly** - модификатор по умолчанию, не имеет ключевого слова. к члену класса имеют доступ все классы, в пределах данного пакета 73 | . За пределами пакета член класса имеет модификатор доступа private. Поля и методы с данным модификатором доступа **наследуются**'. 74 | 75 | При подключении пакетов, имеющих одинаковые члены(типы), могут возникать коллизии, для решения которых 76 | при работе с членом надо указывать CLASSPATH. 77 | 78 | ```java 79 | java.util.Vector v = new java.util.Vector(); 80 | ``` 81 | 82 | 83 | 84 | ## Наследование 85 | 86 | **Наследование** - механизм языка, позволяющий создать новые классы на основе уже существующих с полностью 87 | или частично заимствованным функционалом. 88 | 89 | `extends` это ключевое слово, предназначенное для расширения реализации какого-то существующего класса. Создается 90 | новый класс на основе существующего, и этот новый класс расширяет (extends) возможности старого. 91 | 92 | `implements` это ключевое слово, предназначенное для реализации интерфейса (interface). 93 | 94 | Для переопределения метода используется аннотация `@Override` 95 | 96 | Однако наследование не всегда является хорошей практикой, и его следует использовать с осторожностью по следующим причинам: 97 | 98 | 1. **Жесткая связь между классами**: Наследование создает жесткую связь между родительским и дочерним классами. 99 | Изменения в родительском классе могут повлиять на все дочерние классы, что может стать проблемой при обслуживании и развитии кодовой базы. 100 | Нежелательные изменения в родительском классе могут привести к непредсказуемым поведениям в дочерних классах. 101 | 2. **Нарушение инкапсуляции**: Наследование может нарушить принцип инкапсуляции, потому что дочерний класс получает доступ 102 | к защищенным и публичным членам родительского класса. Это может сделать сложнее контролировать и обеспечивать целостность 103 | данных и поведения классов. 104 | 3. **Жесткая иерархия классов**: Использование наследования может привести к созданию слишком сложной иерархии классов, 105 | которая затруднит понимание кода и его поддержку. Это может усложнить архитектуру программы и сделать код менее гибким. 106 | 107 | ## Отношения между классами 108 | 109 | - **IS-A**: наследование и релизация интерфейса. 110 | - **HAS-A** (один класс использует другой) отношения: 111 | - Ассоциация - объекты двух классов могут ссылаться друг на друга: 112 | - Агрегация - объект поступает из-вне (более слабая связь). 113 | - Композиция - объект создается внутри конструктора текущего класса (более сильная связь). 114 | 115 | Пример агрегации 116 | ```java 117 | public class Horse { 118 | private Halter halter; 119 | public Horse (Halter halter) { 120 | this.halter = halter; 121 | } 122 | } 123 | ``` 124 | 125 | Пример композиции 126 | ```java 127 | public class Horse { 128 | private Halter halter; 129 | public Horse () { 130 | this.halter = new Halter(); 131 | } 132 | } 133 | ``` 134 | 135 | >По возможности лучше использовать композицию вместо наследования из-за недостатков наследования. 136 | 137 | 138 | 139 | ## Полиморфизм 140 | 141 | **Полиморфизм** - механизм языка позволяющий членам класса с одинаковой иерархией иметь различную реализацию, 142 | многообразие форм. _Одна задача - множество решений_. 143 | 144 | Реализовывается через перегрузки методов. 145 | 146 | 147 | 148 | ## Абстракция 149 | 150 | **Абстрагирование** – это способ выделить набор общих характеристик объекта, исключая из рассмотрения частные и незначимые. 151 | Соответственно, **абстракция** – это набор всех таких характеристик. 152 | 153 | Пример реализация класса **Animal** для создание объекта **pig**. 154 | 155 | 156 | 157 | ## Обмен сообщениями 158 | 159 | Объекты взаимодействуют, **посылая и получая сообщения**. 160 | 161 | **Сообщение** — это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия. В ООП посылка сообщения (вызов метода) — это единственный путь передать управление объекту. Если объект должен «отвечать» на это сообщение, то у него должна иметься соответствующий данному сообщению метод. 162 | Так же объекты, используя свои методы, могут и сами посылать сообщения другим объектам. Обмен сообщениями реализуется с помощью динамических вызовов, что приводит к **чрезвычайно позднему связыванию (extreme late binding)**. 163 | 164 | --- -------------------------------------------------------------------------------- /Notes/Java/string/String.md: -------------------------------------------------------------------------------- 1 | # String 2 | ## Сравнение строк 3 | 4 | Для сравнения строк используются методы `equals()` и `equalsIgnoreCase()`, который не учитывает регистр символов. 5 | 6 | В Java существует так называемый **String Pool**, в котором хранятся **созданные строки**. При создании очередной строки, 7 | JVM сначала ищет такую строку в String Pool. **Если такая строка уже есть, то она возвращается вместо создания новой**. 8 | 9 | **String Pool не используется**, если строка создается с помощью оператора **new**. 10 | `String str = new String();` 11 | 12 | 13 | 14 | Пример: 15 | ```java 16 | public class Equals { 17 | public static void main(String[] args) { 18 | String str1 = "one"; 19 | String str2 = "one"; 20 | String str3 = new String("one"); 21 | 22 | System.out.println(str1 == str2); 23 | System.out.println(str3 == str1); 24 | } 25 | } 26 | ``` 27 | Результат: 28 | 29 | ``` 30 | true 31 | false 32 | ``` 33 | 34 | ## Сортировка строк 35 | 36 | Для сортировки строк можно использовать метод `compareTo()`. 37 | 38 | Резултат работы `String str1.compareTo(str2)`: 39 | - _<0_ - str1 < str2; 40 | - _==_ 0 - строки эквивалентны; 41 | - _>0_ - str1 > str2. 42 | 43 | ## Методы isEmpty(), isBlank() 44 | Метод `isEmpty()` проверяет пустая ли строка. Возвращает true, только если длина строки равна 0. 45 | 46 | Метод `isBlank()` возвращает true, если строка пуста или содержит только пробелы (Java 11). 47 | 48 | # Отличие StringBuilder и StringBuffer 49 | 50 | Классы StringBuilder и StringBuffer **используются**, когда возникает необходимость сделать **много изменений в строке**. 51 | 52 | Класс **String** - **неизменяемый**, в то время как **StringBuilder и StringBuffer изменяемы**. 53 | 54 | > Методы StringBuffer является безопасными для потоков (синхронизированны), а методы StringBuilder - не безопасны. 55 | 56 | > Методы StringBuilder быстрее, чем методы StringBuffer. 57 | 58 | ## Основные методы 59 | 60 | - `charAt(индекс символа)` - возвращает символ в указанной позиции; 61 | - `setCharAt(1, 'i')` - изменяет символ в указанной позиции; 62 | - `append("I Java!")` - присоединяет подстроку к строке; 63 | - `insert(2, "like ")` - вставляет подстроку в указанную позицию; 64 | - `reverse()` - инвертирует строку; 65 | - `delete(4, 7)` - удаляет подстроку включая с первого символа не включая последний символ; 66 | - .replace(1, 5, "=============") - заменяет подстроку включая с первого символа не включая последний символ на другую 67 | подстроку; 68 | -------------------------------------------------------------------------------- /Notes/Java/string/assets/stringPool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Java/string/assets/stringPool.png -------------------------------------------------------------------------------- /Notes/Java/threads/assets/threadLifeCycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Java/threads/assets/threadLifeCycle.png -------------------------------------------------------------------------------- /Notes/Java/threads/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Java/threads/img.png -------------------------------------------------------------------------------- /Notes/Java/threads/threads_.md: -------------------------------------------------------------------------------- 1 | ## Потоки vs процессы 2 | 3 | В начале выполнения процесс состоит из одного потока. Потоки могут создавать новые потоки в пределах одного процесса. 4 | 5 | Все потоки имеют общие сегменты кода и данных, что позволяет им взаимодействовать друг с другом. 6 | 7 | Каждый поток имеет свой отдельный стек выполнения. И важный момент — единицей планирования операционной системы является поток. 8 | 9 | Поток — это абстракция для операционной системы. 10 | 11 | В некоторых языках программирования, например C, мы можем написать программу, которая будет выполняться без потоков прямо на железе. В Java такое выполнить невозможно. 12 | 13 | Так как операционная система занимается управлением ресурсов, в любой момент ОС сможет усыпить поток и передать вычислительные ресурсы для другого потока. 14 | 15 | Отсутствует гарантия, что поток доживет до какой-то точки. Его в любой момент могут завершить снаружи. 16 | 17 | Также отсутствует гарантия завершения потока, мы снаружи принудительно не сможем завершить поток, придется дожидаться, пока поток сам завершится. 18 | 19 | Стоит тут так же отметить, что существует возможность случайного пробуждения. Его следует корректно обрабатывает в тех случаях, когда мы с помощью операции sleep пытаемся усыпить свой поток. После пробуждения, мы должны вновь проверить наступление ожидаемого условия иначе же заснуть. Мы еще ни раз обратим внимание на этот момент. 20 | 21 | Рассмотрим плюсы и минусы применения множества потоков и множества процессов. 22 | 23 | Потоки: 24 | 25 | Быстрее создаются. 26 | Проще код. 27 | Быстрее обмен данными. 28 | Процессы: 29 | 30 | Надежность (обрабатываем ошибки). 31 | Безопасность (один процесс не сможет прочитать данные другого). 32 | 33 | Если для общения потоков друг с другом используется общая память, то для межпроцессного взаимодействия есть целый ряд возможных способов связи. 34 | 35 | Межпроцессные взаимодействия Inter-process communication IPC могут быть следующими: 36 | 37 | файл; 38 | сигнал; 39 | сокет; 40 | канал; 41 | именованный канал; 42 | неименованный канал; 43 | семафор; 44 | разделяемая память; 45 | обмен сообщениями; 46 | проецируемый в память файл (mmap); 47 | очередь сообщений; 48 | почтовый ящик. 49 | 50 | Есть две характеристики: latency (время ожидания) и thoughput (пропускная способность). В сравнении с примером слева пропускная способность кода справа выше, но и в то же время задержка увеличилась. 51 | 52 | Просто так распараллеливать и получать ускорение с каждым потоком у нас не получится. 53 | 54 | Закон Амдала показывает зависимость доли параллельного кода, количества вычислителей, то есть потоков к приросту производительности. То есть, увеличив количество параллельного кода до 95%, мы получим теоретическое максимальное ускорение в размере двадцатикратного прироста. Дальнейшее увеличение числа параллельных вычислителей уже не будет давать прироста производительности. 55 | ![img.png](img.png) 56 | 57 | ## 5 основных способов синхронизации коллекций 58 | 59 | Линеаризуемость — для всех вариантов синхронизации. 60 | 61 | Deadlock-free, Starvation-free — для подходов с блокировками. 62 | 63 | Напомню, что линеаризуемостью называется свойство системы, при котором параллельное выполнение эквивалентно последовательному. То есть мы можем выстроить такую последовательность параллельных действий, при которых будет возможно финальное состояние системы. И оно будет выполняться в интервале от начала операции до ее завершения. И момент выполнения этого действия, лежащий в этом интервале, называется точкой линеаризации. 64 | 65 | Deadlock-free — это гарантия, которая защищает от взаимных блокировок. 66 | 67 | Starvation-free — это гарантия, при которой поток гарантированно выйдет из состояния блокировки и исключаются случаи, когда поток будет заблокирован на неопределенное время. 68 | 69 | -------------------------------------------------------------------------------- /Notes/Spring/DataJpa/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Spring/DataJpa/img.png -------------------------------------------------------------------------------- /Notes/Spring/DataJpa/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Spring/DataJpa/img_1.png -------------------------------------------------------------------------------- /Notes/Spring/Security/README.md: -------------------------------------------------------------------------------- 1 | # Spring Security 2 | 3 | Зависимость 4 | ```java 5 | 6 | org.springframework.boot 7 | spring-boot-starter-security 8 | 9 | ``` 10 | ## Файл конфигурации 11 | 12 | Объявляет bean-компонент `PasswordEncoder`, используемый для содания новых пользователей при аутентификации 13 | - BCryptPasswordEncoder - применяет надежное шифрование bcrypt; 14 | - NoOpPasswordEncoder – не применяет шифрования (для тестирования); 15 | - StandardPasswordEncoder – применяет шифрование SHA-256 (устарел); 16 | 17 | 18 | 19 | ## InMemoryUserDetailsManager 20 | 21 | Хранилище, в котором хранятся пользователи. 22 | 23 | Роли хранятся в отдельном перечислении: 24 | ```java 25 | public enum Role { 26 | USER, 27 | ADMIN; 28 | } 29 | ``` 30 | Файл конфигурации: 31 | 32 | ```java 33 | @Configuration 34 | @EnableWebSecurity 35 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 36 | @Override 37 | protected void configure(HttpSecurity http) throws Exception { 38 | http 39 | // Защита от csrf угроз 40 | .csrf().disable() 41 | .authorizeRequests() 42 | // Кто в какие URL имеет доступ 43 | .antMatchers("/").permitAll() 44 | // Какие методы HTTP запроса разрешены каким ролям 45 | .antMatchers(HttpMethod.GET, "/api/**").hasAnyRole(Role.ADMIN.name(), Role.USER.name()) 46 | .antMatchers(HttpMethod.POST, "/api/**").hasRole(Role.ADMIN.name()) 47 | .antMatchers(HttpMethod.DELETE, "/api/**").hasRole(Role.ADMIN.name()) 48 | // Каждый из запросов должен аутентифицироваться 49 | .anyRequest().authenticated().and().httpBasic(); 50 | } 51 | 52 | @Bean 53 | @Override 54 | public UserDetailsService userDetailsServiceBean() throws Exception { 55 | // Создание ролей 56 | return new InMemoryUserDetailsManager( 57 | User.builder() 58 | .username("admin") 59 | .password(passwordEncoder().encode("admin")) 60 | .roles(Role.ADMIN.name()) 61 | .build(), 62 | User.builder() 63 | .username("user") 64 | .password(passwordEncoder().encode("user")) 65 | .roles(Role.USER.name()) 66 | .build() 67 | ); 68 | } 69 | 70 | @Bean 71 | protected PasswordEncoder passwordEncoder() { 72 | return new BCryptPasswordEncoder(12); 73 | } 74 | } 75 | 76 | ``` 77 | 78 | ## Авторизация с использованием прав доступа | authorities 79 | 80 | Каждой роли присваивается определенное количество прав. 81 | 82 | Создание новой сущности `Permission`: 83 | ```java 84 | public enum Permission { 85 | DEVELOPERS_READ("developers:read"), 86 | DEVELOPERS_WRITE("developers:write"); 87 | 88 | private final String permission; 89 | 90 | Permission(String permission) { 91 | this.permission = permission; 92 | } 93 | 94 | public String getPermission() { 95 | return permission; 96 | } 97 | } 98 | ``` 99 | 100 | Изменим Enum `Role` 101 | 102 | ```java 103 | public enum Role { 104 | // Выдаем permission созданным ролям 105 | USER(Set.of(Permission.DEVELOPERS_READ)), 106 | ADMIN(Set.of(Permission.DEVELOPERS_READ, Permission.DEVELOPERS_WRITE)); 107 | 108 | private final Set permissions; 109 | 110 | Role(Set permissions) { 111 | this.permissions = permissions; 112 | } 113 | 114 | public Set getPermissions() { 115 | return permissions; 116 | } 117 | 118 | // Преобразовывем permission в authority 119 | public Set getAuthorities() { 120 | return getPermissions().stream() 121 | .map(permission -> new SimpleGrantedAuthority(permission.getPermission())) 122 | .collect(Collectors.toSet()); 123 | } 124 | } 125 | ``` 126 | Меняем в файле конфигурации проверку наличия ролей на проверку наличия прав: 127 | ```java 128 | @Override 129 | protected void configure(HttpSecurity http) throws Exception { 130 | http 131 | // Защита от csrf угроз 132 | .csrf().disable() 133 | .authorizeRequests() 134 | // Кто в какие URL имеет доступ 135 | .antMatchers("/").permitAll() 136 | // Какими правами надо обладать для использования HTTP меодов 137 | .antMatchers(HttpMethod.GET, "/api/**").hasAuthority(Permission.DEVELOPERS_READ.getPermission()) 138 | .antMatchers(HttpMethod.POST, "/api/**").hasAuthority(Permission.DEVELOPERS_WRITE.getPermission()) 139 | .antMatchers(HttpMethod.DELETE, "/api/**").hasAuthority(Permission.DEVELOPERS_WRITE.getPermission()) 140 | // Каждый из запросов должен аутентифицироваться 141 | .anyRequest().authenticated().and().httpBasic(); 142 | } 143 | ``` 144 | При создании пользователей вместо ролей присваиваем права: 145 | ```java 146 | @Bean 147 | @Override 148 | public UserDetailsService userDetailsServiceBean() throws Exception { 149 | return new InMemoryUserDetailsManager( 150 | User.builder() 151 | .username("admin") 152 | .password(passwordEncoder().encode("admin")) 153 | .authorities(Role.ADMIN.getAuthorities()) 154 | .build(), 155 | User.builder() 156 | .username("user") 157 | .password(passwordEncoder().encode("user")) 158 | .authorities(Role.USER.getAuthorities()) 159 | .build() 160 | ); 161 | } 162 | ``` 163 | 164 | ## Аннотация `@PreAuthorize` 165 | 166 | **Разрешить вызов метода только пользователю с конкретными правами.** 167 | 168 | В контроллере определяем права для методов: 169 | ```java 170 | @GetMapping("/{id}") 171 | // ! 172 | @PreAuthorize("hasAnyAuthority('developers:read')") 173 | // ! 174 | public Developer getById(@PathVariable Long id) { 175 | return DEVELOPERS.stream().filter(developer -> developer.getId().equals(id)) 176 | .findFirst() 177 | .orElse(null); 178 | } 179 | 180 | @PostMapping 181 | // ! 182 | @PreAuthorize("hasAnyAuthority('developers:write')") 183 | // ! 184 | public Developer create(@RequestBody Developer developer) { 185 | this.DEVELOPERS.add(developer); 186 | return developer; 187 | } 188 | 189 | @DeleteMapping("/{id}") 190 | // ! 191 | @PreAuthorize("hasAnyAuthority('developers:write')") 192 | // ! 193 | public void deleteById(@PathVariable Long id) { 194 | this.DEVELOPERS.removeIf(developer -> developer.getId().equals(id)); 195 | } 196 | ``` 197 | 198 | **Настройка SecurityConfig**. Добавляем специальную аннотацию, часть кода можно убрать 199 | ```java 200 | //! 201 | @EnableGlobalMethodSecurity(prePostEnabled = true) // Позволяет использовать @PreAuthorize 202 | //! 203 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 204 | @Override 205 | protected void configure(HttpSecurity http) throws Exception { 206 | http 207 | // Защита от csrf угроз 208 | .csrf().disable() 209 | .authorizeRequests() 210 | // Кто в какие URL имеет доступ 211 | .antMatchers("/").permitAll() 212 | // Каждый из запросов должен аутентифицироваться 213 | .anyRequest().authenticated().and().httpBasic(); 214 | } 215 | ``` 216 | 217 | ## Аутентификация с использованием формы ввода 218 | Вместо `.httpBasic()` применяется `.formLogin()` 219 | ```java 220 | @Override 221 | protected void configure(HttpSecurity http) throws Exception { 222 | http 223 | // Защита от csrf угроз 224 | .csrf().disable() 225 | .authorizeRequests() 226 | // Кто в какие URL имеет доступ 227 | .antMatchers("/").permitAll() 228 | // Каждый из запросов должен аутентифицироваться 229 | .anyRequest() 230 | .authenticated() 231 | .and() 232 | .formLogin() 233 | // Адрес 234 | .loginPage("/auth/login").permitAll() 235 | // Если успешно, то перенаправляемся на URL 236 | .defaultSuccessUrl("/auth/success") 237 | .and() 238 | //логаут 239 | .logout() 240 | //проводится по пути с методом 241 | .logoutRequestMatcher(new AntPathRequestMatcher("/auth/logout", "POST")) 242 | //после чего сессия закрывается 243 | .invalidateHttpSession(true) 244 | .clearAuthentication(true) 245 | .deleteCookies("JSESSIONID") 246 | // После логаута перенаправляемся на 247 | .logoutSuccessUrl("/auth/login") 248 | ; 249 | } 250 | ``` 251 | **Создание формы логина**. Метод POST отправляется на контроллер "/auth/login" 252 | ```html 253 | 254 | 255 | 256 | Login Customer 257 | 258 | 259 |
260 | 272 |
273 | 274 | 275 | ``` 276 | Использования метода запроса GET для логаута является небезопасным. Поэтому сделаем POST 277 | метод. 278 | 279 | Форма для Logout 280 | ```html 281 |
282 | 283 |
284 | ``` 285 | 286 | ## Аутентификация и авторизация при помощи БД -------------------------------------------------------------------------------- /Notes/Spring/Spring-reaper.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Spring/Spring-reaper.md -------------------------------------------------------------------------------- /Notes/Spring/boot/README.md: -------------------------------------------------------------------------------- 1 | ## Содержание 2 | 3 | * [Spring Boot](#springBoot) 4 | * [Spring Validator](#validator) 5 | --- 6 | 7 | 8 | 9 | # Spring Boot 10 | 11 | `@SpringBootApplication` - указывает, что это приложение Spring Boot, составная аннотация, объединяющая три другие 12 | аннотации: 13 | 14 | - `@SpringBootConfiguration` - определяет класс как конфигурационный. (Специализированная форма аннотации `@Configuration`) 15 | - `@EnableAutoConfiguration` - включает автоконфигурацию Spring Boot 16 | - `@ComponentScan` - включает сканирование компонентов. Механизм сканирования позволяет объявлять другие классы с аннотациями, 17 | такими как @Component, @Controller, @Service, чтобы Spring автоматически обнаруживал и регистрировал их как компоненты в 18 | контексте приложения Spring. 19 | 20 | ## Spring Boot Dev Tools 21 | 22 | Набор дополнительных инструментов, позволяющих: 23 | - автоматически перезапускать приложение при изменении кода; 24 | - автоматически обновлять окно браузера при изменении ресурсов, передаваемых браузеру; 25 | - автоматически отключать кеширование шаблонов; 26 | - открывать встроенную консоль Н2, при применении соответствующей БД. 27 | 28 | 29 | 30 | ## Spring Validator 31 | 32 | Реализовывает интерфейс `Validator` 33 | 34 | ```java 35 | 36 | // Метод в DAO который проверяет, имеется ли уже пользователь с таким email 37 | public Optional show(String email) { 38 | return jdbcTemplate.query("SELECT * FROM person WHERE email=?", new Object[]{email}, 39 | new BeanPropertyRowMapper<>(Person.class)).stream().findAny(); 40 | } 41 | 42 | ``` 43 | ```java 44 | @Component 45 | public class PersonValidator implements Validator { 46 | 47 | private final PersonDAO personDAO; 48 | 49 | @Autowired 50 | public PersonValidator(PersonDAO personDAO) { 51 | this.personDAO = personDAO; 52 | } 53 | 54 | @Override 55 | public boolean supports(Class clazz) { 56 | return Person.class.equals(clazz); 57 | } 58 | 59 | @Override 60 | public void validate(Object target, Errors errors) { 61 | Person person = (Person) target; 62 | // Посмотреть, есть ли человек с таким же email в БД 63 | if (personDAO.show(person.getEmail()).isPresent()) { 64 | // параметры: 1 - какое поле вызвало ошибку, 2 - код ошибки, 3 - сообщение ошибки 65 | errors.rejectValue("email", "", "Пользователь с данным email уже зарегистрирован"); 66 | } 67 | } 68 | } 69 | ``` 70 | 71 | Добавляем валидатор в методы контроллера 72 | ```java 73 | @PostMapping 74 | public String createNewPerson(@ModelAttribute("person") @Valid Person person, BindingResult bindingResult) { 75 | personValidator.validate(person, bindingResult); //!!!!!!!!!!!!!!!!!!!!!!!!!!!! 76 | 77 | if (bindingResult.hasErrors()) { 78 | return "people/newPerson"; 79 | } 80 | personDAO.save(person); 81 | return "redirect:/people"; 82 | } 83 | 84 | 85 | 86 | @PatchMapping("/{id}") 87 | public String update(@ModelAttribute("person") @Valid Person person, BindingResult bindingResult, 88 | @PathVariable("id") int id) { 89 | personValidator.validate(person, bindingResult); //!!!!!!!!!!!!!!!! 90 | if (bindingResult.hasErrors()) { 91 | return "people/edit"; 92 | } 93 | personDAO.update(id, person); 94 | return "redirect:/people"; 95 | } 96 | 97 | ``` 98 | 99 | -------------------------------------------------------------------------------- /Notes/Spring/boot/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/Spring/boot/img.png -------------------------------------------------------------------------------- /Notes/Spring/core/Annotations.md: -------------------------------------------------------------------------------- 1 | 2 | # Конфигурация Spring приложения. XML + Аннотации 3 | 4 | ## Содержание 5 | 6 | * [Аннотации](#Annotations) 7 | * [Внедрение зависимостей с помощью аннотаций](#DI) 8 | 9 | --- 10 | 11 | 12 | ## Аннотации 13 | ```java 14 | 15 | ``` 16 | 17 | **Аннотации** - специальный тип комментариев, с помощью которых можно 18 | - передавать инструкции для Java-компилятора (Например, `@Override`) 19 | - передавать инструкции для анализаторов исхдного кода 20 | - передавать метаданные, которые могут быть использованы либо Java приложением (с помощью рефлексии), либо другими 21 | приложениями или фреймворками (Например, Spring) 22 | 23 | > Преимущества аннотаций: короче и удобнее, чем XML конфигурация, код становится более читабельным. 24 | 25 | `@Component` - пометка на создание бина из класса 26 | 27 | --- 28 | 29 | 30 | 31 | 32 | ## Внедрение зависимостей с помощью аннотаций 33 | 34 | Класс, в который нужно внедрить зависимость помечается аннотацией `@Autowired` (подбирает бины по 35 | типу (класс или интерфейс)). 36 | 37 | Принцип работы: 38 | 1. Spring сканирует все классы с аннотацией `@Component` и создает бины 39 | 2. Spring сканирует все бины и проверяет, подходит ли хотя бы один бин в качестве зависимости там, 40 | где есть аннотация `@Autowired` 41 | 3. Если находится подходящий бин, он внедряется в качестве зависимости. Не находится - ошибка. 42 | Подходят несколько - неоднозначность 43 | 44 | > Аннотацию `@Autowired` можно использовать на полях, сеттерах и конструкторах. Причем `@Autowired` 45 | внедрит зависимость в приватное поле, даже если нет конструктора или сеттера. Делает это она с помощью 46 | рефлексии (Java Reflection API) 47 | 48 | ### @Qualifier(id) 49 | 50 | Уточняет id бина для внедрения 51 | ```java 52 | @Autowired 53 | public MusicPlayer(@Qualifier("rockMusic") Music music1, @Qualifier("classicalMusic") Music music2) { 54 | this.music1 = music1; 55 | this.music2 = music2; 56 | } 57 | ``` 58 | 59 | ### @Value 60 | 1. Создание файла .properties 61 | 2. ` 29 | 30 | ## DI / IoC 31 | 32 | **IoC (Inversion of Control)** - Инверсия управления - архитектурный подход, при котором сущность не сама создает свои 33 | зависимости, а зависимости подаются извне. 34 | 35 | Может реализовываться как механизм передачи процесса выполнения кода/программы 36 | фреймворку. При использовании библиотеки вы сами прописываете в своем коде какой метод какого объекта вызвать, а в 37 | случае с фреймворками — чаще всего уже фреймворк будет вызывать в нужный ему момент тот код, который вы написали. То есть 38 | , тут уже не вы управляете процессом выполнения кода/программы, а фреймворк это делает за вас. Вы передали ему управление 39 | (инверсия управления). 40 | 41 | **Dependency Inversion** - инверсия зависимостей - попытки не делать жестких связей между вашими модулями/классами, 42 | где один класс напрямую завязан на другой; 43 | 44 | **Dependency Injection** - Внедрение зависимости — процесс предоставления внешней зависимости программному компоненту. 45 | Вместо ручного создания объектов в мейне их создает Спринг и передает их в методы по конфигурации. 46 | 47 | В технологии внедрения зависимостей компоненты не создают и не поддерживют жизненный цикл других компонентов компонентов, 48 | от которых он зависят, а полагаются в этом на отдельный объект (контейнер), который создаст все нужные компоненты и внедрит 49 | их в другие пкомпоненты, которые в них нуждаются. 50 | 51 | --- 52 | 53 | 54 | 55 | ## Типичные шаги в работе со Spring 56 | 1. Создаем Java-классы (Будущие бины); 57 | 2. Создаем и связываем бины с помощью Spring (Аннотации, XML, или Java-код); 58 | 3. При использовании, все объекты (бины) берутся из контейнера Spring 59 | 60 | --- 61 | 62 | 63 | 64 | ## Application context 65 | 66 | **Контекст** - набор бинов (объектов). Обращаясь к контексту можно получить нужный бин (объект) по его имени, 67 | типу или чему-то еще. 68 | 69 | > applicationContext.xml создается в папке resources 70 | 71 | 72 | 73 | ### Жизненный цикл бина 74 | 75 | 1. Запуск Spring приложения 76 | 2. Запускается Spring контейнер (Application Context) 77 | 3. Создается объект бина 78 | 4. В бин внедряются зависимости (Dependency Injection) 79 | 5. Вызывается указанный **init-method**, отвечающий за инициализацию ресурсов, обращение к внешним файлам, запуск БД 80 | 6. Бин готов к использованию 81 | 7. Вызывается указанный **destroy-method**, отвечающий за очищение ресурсов, закрытие потоков ввода-вывода, закрытие доступа 82 | к бд. 83 | 8. Остановка Spring приложения 84 | 85 | > Для бинов со scope "prototype" Spring **не вызывает destroy метод** 86 | 87 | Пример: 88 | ```java 89 | 93 | 94 | 95 | // Методы создаются в классе бина 96 | ``` 97 | 98 | ### Способы конфигурации приложения 99 | 100 | Указать спрингу, какие именно объекты нужны для работы можно тремя способами, которые можно комбинировать 101 | между собой: 102 | 1. **Автоматическая конфигурация** - наиболее приоритетный способ 103 | 2. При помощи **java-конфигов** (создание объектов, используя java-код) 104 | 3. При помощи **xml файлов/конфигов** - самый низкоприоритетный способ 105 | 106 | --- 107 | 108 | 109 | 110 | ## Способы внедрения зависимостей 111 | Внедряемый бин 112 | ```java 113 | 115 | 116 | ``` 117 | 118 | ### Через конструктор (передавать в конструктор одного объекта другой) 119 | ```java 120 | public MusicPlayer(Music music) { this.music = music;} 121 | 122 | 123 | // Ссылка на объект 124 | 125 | ``` 126 | ### Через setter 127 | Внедрение ссылки на объект 128 | ```java 129 | public void setMusic(Music music) { 130 | this.music = music; 131 | } 132 | 133 | 134 | 135 | 136 | 137 | ``` 138 | Внедрение простых значений 139 | ```java 140 | private String name; 141 | private String volume; 142 | 143 | public void setName(String name) { this.name = name; } 144 | public void setVolume(String volume) { this.volume = volume; } 145 | 146 | 147 | 148 | 149 | ``` 150 | Внедрение значений из файла 151 | >Файл с расширением `.properties` в каталоге resources 152 | ```java 153 | // musicPlayer.properties: 154 | //musicPlayer.name=SomeName 155 | //musicPlayer.value=70 156 | 157 | 158 | 159 | 160 | 161 | 162 | ``` 163 | 164 | ## Конфигурации внедрения (scope, init-method, destroy-method, factory method); 165 | 166 | ### Scope 167 | 168 | **Scope** наборы паттернов, по которым Spring создает бины. 169 | 170 | - По умолчанию используется **singleton**. Применяется когда у бина нет изменяемых состояний (stateless). 171 | - **Prototype**, каждый раз создающий новый объект при вызове `getBean()`. Применяется когда у бина есть изменяемые 172 | состояния (stateful). 173 | - request 174 | - session 175 | - global-session 176 | 177 | Пример 178 | ```java 179 | class="MusicPlayer" scope="prototype"> 180 | ``` 181 | 182 | ## 183 | 184 | * XML, аннотации или Java-код; 185 | * Автоматизация (Autowiring); 186 | 187 | --- -------------------------------------------------------------------------------- /Notes/Spring/core/javaCode.md: -------------------------------------------------------------------------------- 1 | # Конфигурация Spring приложения. Аннотации + Java код 2 | 3 | ```java 4 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); 5 | ``` 6 | 7 | ## Аннотация @Configuration 8 | 9 | Помечает Java класс, который мы хотим использовать для конфигурации Spring приложения. 10 | 11 | ```java 12 | @Configuration 13 | public class SpringConfig{ 14 | } 15 | ``` 16 | 17 | Пустой конфигурационный Java класс равен по фунционалу пустому конфигурационному XML файлу 18 | 19 | ## XML теги и соответствующие аннотации 20 | 21 | | XML | Аннотация | 22 | |------------------------------------------------------------------------|------------------------------------------------| 23 | | `` | `@ComponentScan("директория с компонентами")` | 24 | | ` ` | `@Bean` | 25 | | `` | `@PropertySource("classpath:файл.properties")` | 26 | 27 | ### Ручное внедрение зависимостей 28 | 29 | ```java 30 | @Configuration 31 | public class SpringConfig { 32 | 33 | @Bean 34 | @Scope("singleton") 35 | public ClassicalMusic musicBean() { // beanId = musicBean 36 | return new ClassicalMusic(); 37 | } 38 | 39 | @Bean 40 | public MusicPlayer musicPlayer() { // beanId = musicPlayer 41 | return new MusicPlayer(musicBean()); // Внедрение созданного бина 42 | } 43 | } 44 | ``` -------------------------------------------------------------------------------- /Notes/Spring/mvc/README.md: -------------------------------------------------------------------------------- 1 | # Spring MVC 2 | 3 | * [DispatcherServlet](#DispatcherServlet) 4 | * [Controller](#Controller) 5 | * [Mapping](#Mapping) 6 | * [@RequestMapping](#RequestMapping) 7 | * [@RequestParam](#RequestMapping) 8 | * [Model](#Model) 9 | * [@ModelAttribute](#ModelAttribute) 10 | * [View](#View) 11 | * [Thymeleaf](#thymeleaf) 12 | * [Синтаксис](#th:synt) 13 | * [Форма | th:method | th:action | th:object](#th:form) 14 | * [Перебор Элементов | th:each](#th:each) 15 | 16 | Предполагает разработку web-приложений с использованием архитектуры Model - View - Controller. 17 | 18 | 19 | 20 | ## MVC | Model - View - Controller 21 | 22 | - `Model` - логика работы с данными (обращение к БД) 23 | - `View` - логика представления, интерфейс 24 | - `Controller` - логика навигации, обработки запросов 25 | 26 | 27 | 28 | --- 29 | 30 | ## DispatcherServlet 31 | 32 | Входная точка Spring MVC приложения. Находится между `Controller` 33 | и `HTTP Request` 34 | 35 | HTTP запрос от пользователя: 36 | 1. Приходит на сервер. Сервер обрабатывает запрос и передает 37 | его на Spring MVC приложение. 38 | 2. Запрос попадает в DispatcherServlet. 39 | 3. DispatcherServlet отправляет запрос на правильный контроллер. 40 | 41 | 42 | 43 | --- 44 | 45 | # Controller 46 | 47 | - `@Controller` 48 | - Обрабатывает запросы от пользователя 49 | - Обменивается данными с моделью 50 | - Показывает пользователю правильное представление 51 | - Переадресовывает пользователя на другие страницы 52 | 53 | `@Controller` - тот же `@Component`, но с дополнительными возможностями. 54 | В контроллере может быть несколько методов, которые возвращают строки - названия представлений, которые нужно показать 55 | пользователю. Обычно каждый метод соответствует одному URL'у 56 | 57 | 58 | 59 | ### Маппинги 60 | 61 | Связывают метод контроллера с адресом, по которому к этому можно к этому методу обратиться (из браузера, например) 62 | 63 | ```java 64 | @Controller 65 | public class HelloController { 66 | @GetMapping("/hello-world") 67 | public String sayHello() {return "hello_world"; } 68 | } 69 | ``` 70 | 71 | 72 | 73 | 74 | #### @RequestMapping 75 | 76 | Используется для того, чтобы указать, что **ВСЕ МЕТОДЫ** класса в начале адреса имели префикс 77 | 78 | ```java 79 | @Controller 80 | @RequestMapping("/people" 81 | public class PersonController { 82 | @GetMapping("/new") // обрабатывает запросы /people/new 83 | public String new() { return "new"; } 84 | 85 | @GetMapping("/old") // обрабатывает запросы /people/old 86 | public String old() { return "old"; } 87 | } 88 | ``` 89 | 90 | 91 | 92 | #### @RequestParam 93 | 94 | Обработка параметров GET-запроса 95 | ```java 96 | @GetMapping("/hello") 97 | public String helloPage(@RequestParam(value = "name", required = false) String name, 98 | @RequestParam(value = "surname", required = false) String surname) { 99 | 100 | System.out.println("Hello, " + name + " " + surname); 101 | 102 | return "first/hello"; 103 | } 104 | 105 | // URL: localhost/hello?name=nikita&surname=bereznev 106 | // Result: Hello, nikita bereznev 107 | ``` 108 | 109 | ### HTTP 110 | 111 | [Примеры запросов](../../Architecture/REST/README.md/#examples) 112 | 113 | 114 | 115 | #### HTTP-Запросы(методы) 116 | 117 | | HTTP метод | Аннотация | Описание | 118 | |------------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 119 | | GET | @GetMapping | Самый используемый запрос. Получение данных с удаленного сервера (переход по адресу, ссылке, поисковой запрос и т.д.). Ничего не меняет на сервере

Параметры нужны для передачи информации от клиента серверу во время запроса. Передаются в самом URL после знака **?** в формате **ключ=значение**. Несколько параметров разделяются знаком **&**.

https://vk.com/audios202613076?q=lilpeep§ion=playlist Параметры (**?q=lilpeep§ion=playlist**) | 120 | | POST | @PostMapping | Добавить на сервер (отправка данных с веб-форм, создать учетную запись, твитнуть, загрузить фото, добавить запись в сообщество). Параметры закодированы в теле запроса. | 121 | | PUT | @PutMapping | Создаёт новый ресурс или заменяет представление целевого ресурса, данными представленными в теле запроса | 122 | | DELETE | @DeleteMapping | Удаляет указанный ресурс | 123 | | PATCH | @PatchMapping | Частично изменяет ресурс | 124 | 125 | 126 | 127 | #### HTTP-Ответы 128 | 129 | * 200 - ОК; 130 | * 3хх - редирект; 131 | * 4хх - ошибка клиента (404 - клиент пытается попасть на несущестующую страницу); 132 | * 5хх - ошибка сервера (502: Bad Gateway - сервер не смог обработать полученный запрос по техническим причинам); 133 | 134 | --- 135 | 136 | 137 | 138 | 139 | # Model 140 | 141 | Контейнер для данных приложения 142 | 143 | - Хранит в себе данные 144 | - Взаимодействует с бд для получения данных 145 | - Отдает данные контроллеру 146 | 147 | 148 | 149 | ## @ModelAttribute 150 | 151 | ### Аннотация метода 152 | 153 | Используется для добавления тех пар ключ-значение, которые нужны во всех моделях этого контроллера. 154 | 155 | ```java 156 | @ModelAttribute("headerMessage") 157 | public String populateHeaderMessage() { 158 | return "Welcome!"; 159 | } 160 | 161 | // Любая модель контроллера по умолчанию будет иметь значение "Welcome!" с ключом headerMessage 162 | ``` 163 | 164 | Может передавать в модель любой объект 165 | ```java 166 | @ModelAttribute("messageObject") 167 | public MessageObject populayeHeaderMessage() { 168 | MessageObject messageObject = new MessageObject(); 169 | messageObject.setSomeField("Hello"); 170 | return messageObject; 171 | } 172 | ``` 173 | 174 | ### Аннотирование аргумента метода 175 | 176 | Создает объект с полями - данными формы и записывает объект в модель. 177 | 178 | ```java 179 | @PostMapping() 180 | public String create(@ModelAttribute("person") Person person) { 181 | //Аннотация создает объект, инициализирует поля данными с формы и записывает объект в модель с ключом "person". 182 | return "sucessPage"; 183 | } 184 | // Если в форме не будет данных, то в модель будет положен новый объект со значениями по умолчанию (0, null, и тд) 185 | ``` 186 | 187 | 188 | 189 | 190 | 191 | 192 | --- 193 | ## View 194 | 195 | - Получает данные от контроллера и отображает их в браузере 196 | - Для динамического отображения данных используются шаблонизаторы 197 | (`Thymeleaf`, `Freemaker`, `Velocity`) 198 | 199 | 200 | 201 | ## Thymeleaf 202 | 203 | 204 | 205 | * Простые выражения: 206 | * **Переменная**: ${...} 207 | * **Выбранная переменная**: *{...} 208 | * **Сообщение**: #{...} 209 | * **Ссылка URL**: @{...} 210 | * **Фрагмент**: ~{...} 211 | * Литералы/Literals: 212 | * **Текст**: 'one text', 'Another one!',... 213 | * **Число**: 0, 34, 3.0, 12.3,... 214 | * **Boolean**: true, false 215 | * **Null**: null 216 | * **Токены**: one, sometext, main,... 217 | * Текст: 218 | * **Соединение строк**: + 219 | * **Подстроки**: |The name is ${name}| 220 | * Арифметика: 221 | * **Binary**: +, -, *, /, % 222 | * **Минус (unary operator)**: - 223 | * Boolean: 224 | * **Binary**: and, or 225 | * **Boolean отрицание (unary operator)**: !, not 226 | * Сравнение и равенство: 227 | * **Сравнение**: >, <, >=, <= (gt, lt, ge, le) 228 | * **Равенство**: ==, != (eq, ne) 229 | * Условные: 230 | * **If-then**: (if)? (then) 231 | * **If-then-else**: (if)? (then): (else) 232 | * **Default: (value) ?**: (defaultvalue) 233 | * Специальные токены: 234 | * **No-Operation**: _ 235 | 236 | ### Пример 237 | 238 | Контроллер: 239 | ```java 240 | @GetMapping("/new") 241 | public String newPerson(Model model) { 242 | model.addAttribute("person", new Person()); // добавляем объект по ключу "person" 243 | return "people/new"; // имя представления для отображения 244 | } 245 | ``` 246 | 247 | ### Представление new.html 248 | 249 | 250 | 251 | #### Форма | th:method | th:action | th:object 252 | 253 | ```html 254 |
255 | 256 | 257 | 258 |
259 | 260 | 261 | 262 |
263 | 264 | 265 |
266 | ``` 267 | **th:method**="HTTP метод" 268 | **th:action**="Для какой страницы сохраняем данные" 269 | **th:object**="используемый объект" 270 | 271 |
272 | 273 | 274 | 275 | #### Перебор Элементов | th:each 276 | 277 | ```html 278 |
279 | user 281 |
282 | ``` 283 | 284 | #### Форма для отправки параметров GET запроса 285 | ```html 286 |
287 |
288 | 289 | 290 |
291 |
292 | 293 | 294 |
295 |
296 | 297 |
298 |
299 | ``` 300 | 301 | 302 | https://habr.com/ru/post/350870/ 303 | -------------------------------------------------------------------------------- /Notes/Testing/README.md: -------------------------------------------------------------------------------- 1 | # Junit 2 | 3 | 4 | | Аннотация | Описание | 5 | |------------------------------------------|----------------------------------------------------| 6 | | @Test | Аннотация, указывющая, что метод является тестом. | 7 | | @Displayname("Название теста") | Отображает пользовательское имя теста при запуске. | 8 | | @RepeatedTest(количество_запусков_теста) | Выполнить тест n раз. | 9 | 10 | Пример: 11 | 12 | ```java 13 | @Test 14 | @Displayname("Проверка сложения чисел") 15 | void myNewTest() { 16 | Assertions.assertEquals(5, 5); // Сравнивает значения на равенство 17 | Assertions.assertEquals(345, Math.addExact(300, 45)); 18 | } 19 | ``` 20 | 21 |
22 | 23 | | Аннотация | Описание | 24 | |--------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------| 25 | | @Timeout(value = количество, unit = TimeUnit.тип_единиц_измерения) | Устанавливает время выполнения метода.Если метод будет выполняться дольше заданного времени, то тест провалится. | 26 | 27 | Пример: 28 | 29 | ```java 30 | @Test 31 | @Timeout(value = 1, unit = TimeUnit.SECONDS) 32 | public void test1() { 33 | long currentTime = System.currentTimeMillis(); 34 | while (System.currentTimeMillis() < currentTime + 10000) { 35 | 36 | } 37 | } 38 | // Тест провалится, т.к. установлено времени на выполнение - 1 секунда, а метод выполняется 10 секунд 39 | ``` 40 | 41 |
42 | 43 | ## Тест с параметрами 44 | 45 | | Аннотация | Описание | 46 | |----------------------------------------------|-------------------------------------------------------------------------| 47 | | @ParameterizedTest | Тест с параметрами, требует аннотацию, предоставляющую исходные данные. | 48 | | @ValueSource(тип = {значения через запятую}) | Передать значения переменных (int, double, string и т.д.) . | 49 | 50 | Пример: 51 | 52 | ```java 53 | @ParameterizedTest 54 | @ValueSource(ints = {4, 621, 265}) 55 | public void isPrimeForNotPrimes(int number) { 56 | Assert.assertFalse(numberWorker.isPrime(number)); 57 | } 58 | ``` 59 | 60 |
61 | 62 | | Аннотация | Описание | 63 | |-----------------------------------------------------|-----------------------------------------------------------| 64 | | @MethodSource("Имя метода, генерирующего значения") | Параметры предоставляются методом, который их генерирует. | 65 | 66 | Пример: 67 | 68 | ```java 69 | public static Stream sourceProvider() { 70 | return Stream.of( 71 | arguments(1, "один"), 72 | arguments(2, "два") 73 | ); 74 | } 75 | 76 | @ParameterizedTest 77 | @MethodSource("sourceProvider") 78 | @DisplayName("test: проверка sourceProvider") 79 | public void test(int num, String str) { 80 | Assertions.assertTrue(str.length() > 0); 81 | Assertions.assertTrue(num == 1 || num == 2); 82 | } 83 | ``` 84 | 85 |
86 | 87 | | Аннотация | Описание | 88 | |-----------------------------------------|--------------------------------------| 89 | | @CsvFileSource(resources = "/data.csv") | Параметры считываются из .csv файла. | 90 | 91 | Пример: 92 | 93 | ```java 94 | @ParameterizedTest 95 | @CsvFileSource(resources = "/data.csv") 96 | public void checkSumDigit(int number, int sum) { 97 | Assert.assertEquals(sum, numberWorker.digitSum(number), 1e-9); 98 | } 99 | ``` 100 | 101 | ## @BeforeEach, @BeforeAll, @AfterEach, @AfterAll 102 | 103 | **@BeforeEach**: 104 | - Используется когда нужно выполнить определенные действия перед каждым тестовым методом. 105 | - Пример использования: инициализация объектов, открытие ресурсов (например, подключение к базе данных), загрузка данных и другие подготовительные действия. 106 | 107 | **@BeforeAll**: 108 | - Используется когда нужно выполнить действия перед началом выполнения всех тестов в классе. 109 | - Пример использования: настройка общих ресурсов, которые могут быть разделяемыми между всеми тестами в классе. 110 | 111 | **@AfterEach**: 112 | - Используется когда вам нужно выполнить определенные действия после каждого тестового метода. 113 | - Пример использования: закрытие ресурсов, освобождение памяти, очистка данных после каждого теста. 114 | 115 | **@AfterAll**: 116 | - Используется когда вам нужно выполнить действия после выполнения всех тестов в классе. 117 | - Пример использования: закрытие общих ресурсов, завершение подключения к базе данных и другие завершающие действия. 118 | 119 | --- 120 | 121 | # MockMvc 122 | 123 | **MockMvc** - симулирует запросы и получает ответы от контроллеров не запуская веб-сервер. 124 | 125 | ### Конифигурация 126 | 127 | Для использования MockMvc на уровне класса нужно использовать конфигурационную аннотацию `@WebMvcTest`. 128 | Позволяет Spring создать экземпляр MockMvc и связать его с контроллерами. 129 | 130 | ```java 131 | @RunWith(SpringRunner.class) 132 | @WebMvcTest 133 | public class WebLayerTest { 134 | 135 | @Autowired 136 | private MockMvc mockMvc; 137 | } 138 | ``` 139 | 140 | ### Выполнение HTTP-запросов и обработка результатов 141 | 142 | Синтаксис: `perform(тип_http_запроса(эндпоинт))` 143 | 144 | GET-запрос: 145 | ```java 146 | mockMvc.perform(get("/health/check")); 147 | ``` 148 | 149 | GET 150 | ```java 151 | mockMvc.perform(get("/health/check")); 152 | ``` 153 | -------------------------------------------------------------------------------- /Notes/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/1.png -------------------------------------------------------------------------------- /Notes/img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/10.png -------------------------------------------------------------------------------- /Notes/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/2.png -------------------------------------------------------------------------------- /Notes/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/3.png -------------------------------------------------------------------------------- /Notes/img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/4.png -------------------------------------------------------------------------------- /Notes/img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/5.png -------------------------------------------------------------------------------- /Notes/img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/6.png -------------------------------------------------------------------------------- /Notes/img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/7.png -------------------------------------------------------------------------------- /Notes/img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/8.png -------------------------------------------------------------------------------- /Notes/img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/Notes/img/9.png -------------------------------------------------------------------------------- /Notes/maven/Maven.md: -------------------------------------------------------------------------------- 1 | # JAR 2 | 3 | **JAR-файл** — это Java-архив (Java ARchive). Это простой архивный файл, сжатый (иногда с нулевой компрессией) по алгоритму zip. 4 | 5 | Он был создан для удобства распространения программ, написанных на Java. Так как обычная программа содержит сотни, тысячи, а иногда и миллионы файлов. Файл может содержать: 6 | - файл манифеста `META-INF/MANIFEST.MF` 7 | - java-файлы (исходный код) 8 | - class-файлы 9 | - файлы, необходимые для работы программы: картинки, файлы с настройками и прочее (ресурсы) 10 | - электронные подписи, которые позволяют защитить программу от модификации 11 | 12 | **Манифест** - это текстовый файл формата ключ: значение; он содержит описание jar-файла. В нем могут быть следующие ключи: 13 | - **Manifest-Version** - версия манифеста 14 | - **Main-Class** - имя главного класса (должен содержать метод main), такой jar-файл можно запустить как обычный исполняемый файл 15 | - **Class-Path** - позволяет указать CLASSPATH, который необходим для полноценной работы программы 16 | - **SHA-Digest** - контрольная сумма определенного файла внутри архива 17 | 18 | # Maven 19 | 20 | ## Основные фазы сборки 21 | 22 | 1. _compile_ - компилирование проекта; 23 | 2. _test_ - тестирование с помощью JUnit тестов; 24 | 3. _package_ - создание jar файла или war, ear в зависимости от типа проекта; 25 | 4. _integration-test_ - запуск интеграционных тестов; 26 | 5. _install_ - копирование jar (war, ear) в локальный репозиторий; 27 | 6. _deploy_ - публикация файла в удалённый репозиторий. 28 | 29 | При выполнении команды `mvn команда` выполняется текущая команда и все предыдущие. 30 | 31 | ## Фазы clean и site 32 | 33 | Фазы clean и site **выполняются только если специально указаны в строке запуска**. 34 | 35 | **clean** - удаление всех созданных в процессе сборки артефактов: _.class_, _.jar_ и др. файлов. 36 | В простейшем случае результат — просто удаление каталога _target_. 37 | 38 | **site** - предназначена для создания документации. 39 | 40 | Т.к. команда _mvn_ понимает когда ему передают несколько фаз, то **для создания документации "с нуля" выполняют**: 41 | `mvn clean package site` 42 | 43 | # Pom.xml 44 | 45 | ## Корневой элемент 46 | 47 | Корневой элемент , в котором прописана схема облегчающая редактирование и проверку, и версия POM. 48 | ```maven 49 | 50 | 53 | ... 54 | 55 | ``` 56 | 57 | ## Заголовок 58 | 59 | ```maven 60 | com.examclouds 61 | courses 62 | 1.0-SNAPSHOT 63 | ``` 64 | 65 | Тройкой groupId, artifactId, version (далее - GAV) можно однозначно идентифицировать jar файл приложения или библиотеки. 66 | 67 | ## Тег packaging 68 | 69 | Тег __ определяет какого типа файл будет создаваться как результат сборки. Возможные варианты pom, jar, war, ear. 70 | 71 | Тег является необязательным. Если его нет, используется значение по умолчанию - jar. 72 | 73 | ## Зависимости | Dependencies 74 | 75 | Зависимости - следующая очень важная часть pom.xml - тут хранится список всех библиотек (зависимостей) которые 76 | используются в проекте. Каждая библиотека идентифицируется так же как и сам проект - тройкой groupId, artifactId, 77 | version (GAV). Объявление зависимостей заключено в теге ``. 78 | 79 | ### Установка зависимостей 80 | 81 | **Когда вы добавляете зависимость в файл pom.xml** вашего проекта (pom.xml - это файл проекта Maven), 82 | Maven будет автоматически скачивать и устанавливать эту зависимость из репозитория в локальный репозиторий на вашем 83 | компьютере. **Локальный репозиторий** - это каталог, в котором хранятся зависимости, скачанные с **удаленного** 84 | **репозитория** (обычно из репозитория Maven Central). 85 | 86 | Далее, **при сборке вашего проекта или выполнении команды `mvn install`**, Maven будет использовать зависимости из 87 | локального репозитория и добавлять их в проект. Это позволяет использовать код из зависимостей в вашем Java-коде, так как **Maven автоматически включит нужные классы в итоговый JAR-файл или другой артефакт**. 88 | 89 | ### Тег scope 90 | 91 | Кроме GAV при описании зависимости может присутствовать тег ``. Он **используется для указания области видимости** 92 | зависимости в проекте. Это позволяет контролировать, как зависимость будет использоваться во время сборки проекта и на каких этапах она будет доступна. Зависимости с разными областями видимости имеют различное поведение в проекте. 93 | 94 | - **compile** (по умолчанию): зависимость доступна на всех этапах сборки проекта; 95 | - **provided**: зависимость будет доступна во время компилляции и тестирования, но не будет включена в итоговый артифакт; 96 | - **test**: зависимость с областью видимости test используется только во время выполнения тестов, 97 | она не включается в итоговый JAR-файл и не доступна приложению во время выполнения; 98 | - **runtime**: зависимость с областью видимости runtime доступна только во время выполнения приложения, но не используется во время компиляции и тестирования. 99 | 100 | ## Тег build 101 | 102 | Тег не обязательный, так как существуют значения по умолчанию. Этот раздел содержит информацию по самой сборке: 103 | 104 | * где находятся исходные файлы, 105 | * где ресурсы, 106 | * какие плагины используются. 107 | 108 | # Репозитории 109 | 110 | **Репозитории** - это место, где хранятся артефакты: jar файлы, pom файлы, javadoc, исходники. 111 | 112 | Репозитории можно разделить на следующие: 113 | * Локальный репозиторий 114 | * Центральный репозиторий 115 | * Внутренний "Корпоративный" репозиторий 116 | 117 | ## Локальный репозиторий 118 | 119 | Персональный репозиторий для каждого пользователя. Здесь лежат артефакты, которые были скачаны из центрального 120 | репозитория, либо добавлены другим способом. 121 | 122 | ## Центральный репозиторий 123 | 124 | Репозиторий, откуда по умолчанию загружаются проекты. 125 | 126 | ## Корпоративный репозиторий 127 | 128 | Если вы хотите создать свой репозиторий, содержимое которого вы можете полностью контролировать (как локальный), и сделать так, чтобы он был доступен для нескольких человек, вам будет полезен корпоративный репозиторий. Доступ к артефактам можно ограничивать настройками безопасности сервера так, что код ваших проектов не будет доступен извне. 129 | 130 | **Чтобы добавить репозиторий в список, откуда будут скачиваться зависимости**, нужно добавить секцию `repositories` в pom.xml. -------------------------------------------------------------------------------- /architecture.md: -------------------------------------------------------------------------------- 1 | # Слои описания архитектуры 2 | ![img.png](img.png) 3 | 4 | - Бизнес-архитектура - описание предприятия через бизнес-процессы, используемые АС и данные, 5 | которые в них используются 6 | - Информационная архитектура - потоки данных, использующиеся в организациях, процессах, 7 | системах 8 | - Архитектура решений - структура и фунционал приложений, удовлетворяющих потребностям бизнеса 9 | - Интеграционная архитектура - взаимодействие приложений 10 | - Техническая архитектура - инфраструктура и стек для разаботки приложений и развертывания -------------------------------------------------------------------------------- /diagrams/kafak.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/diagrams/kafak.vsdx -------------------------------------------------------------------------------- /diagrams/kafka.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/diagrams/kafka.vsdx -------------------------------------------------------------------------------- /img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CreativeWex/JavaLearning/fcf589df97c1a0a7fa29e36f76a18a05e73a0c9d/img.png -------------------------------------------------------------------------------- /todayLearned.md: -------------------------------------------------------------------------------- 1 | ## @UtilityClass 2 | Аннотация ломбок, которая помогает делать статический класс с приватным конструктором 3 | 4 | ## CatBoost 5 | Библиотека Яндекса для машинного обучения, градиентный бустинг на основе ансамбля слабых 6 | обучающих алгоритмов. 7 | 8 | ## XGBoost, LightGBM, Sci-kit Learn 9 | библиотека для машинного обучения, решает задачи с регуляризацией градиентного бустинга 10 | 11 | # @MappedSuperclass --------------------------------------------------------------------------------