From 2f126aad69b9293f5c6056ae160c015c00fe8708 Mon Sep 17 00:00:00 2001 From: Grigory Kislin Date: Thu, 24 Nov 2016 15:24:25 +0300 Subject: [PATCH 01/71] Init --- .gitignore | 7 +++ README.md | 88 +++++++++++++++++++++++++++++++++++ intro.md | 38 +++++++++++++++ lesson1.md | 60 ++++++++++++++++++++++++ lesson10.md | 19 ++++++++ lesson11.md | 31 ++++++++++++ lesson12.md | 18 +++++++ lesson13.md | 29 ++++++++++++ lesson14.md | 26 +++++++++++ lesson15.md | 26 +++++++++++ lesson16.md | 21 +++++++++ lesson17.md | 24 ++++++++++ lesson2.md | 37 +++++++++++++++ lesson3.md | 21 +++++++++ lesson4.md | 28 +++++++++++ lesson5.md | 13 ++++++ lesson6.md | 20 ++++++++ lesson7.md | 46 ++++++++++++++++++ lesson8.md | 21 +++++++++ lesson9.md | 25 ++++++++++ src/ArrayStorage.java | 30 ++++++++++++ src/MainArray.java | 70 ++++++++++++++++++++++++++++ src/MainTestArrayStorage.java | 39 ++++++++++++++++ src/Resume.java | 13 ++++++ 24 files changed, 750 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 intro.md create mode 100644 lesson1.md create mode 100644 lesson10.md create mode 100644 lesson11.md create mode 100644 lesson12.md create mode 100644 lesson13.md create mode 100644 lesson14.md create mode 100644 lesson15.md create mode 100644 lesson16.md create mode 100644 lesson17.md create mode 100644 lesson2.md create mode 100644 lesson3.md create mode 100644 lesson4.md create mode 100644 lesson5.md create mode 100644 lesson6.md create mode 100644 lesson7.md create mode 100644 lesson8.md create mode 100644 lesson9.md create mode 100644 src/ArrayStorage.java create mode 100644 src/MainArray.java create mode 100644 src/MainTestArrayStorage.java create mode 100644 src/Resume.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..188fae8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.idea +out +*.iml +log + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..8680649 --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# Курс JavaSE + Web + +## Вступительное заниятие + - [Необходимое ПО](intro.md#Необходимое-ПО) + - [Рекомендуемые книги](intro.md#Рекомендуемые-книги) + - [Ресуры в сети](intro.md#Ресуры-в-сети) + - [Вступительное задание](intro.md#Вступительное-задание) + +## Темы курса +### Занятие 1 + - [Разработка ПО](lesson1.md#Разработка-ПО) + - [Обзор языка Java](lesson1.md#Обзор-языка-java) + - [Системы управления версиями. Git](lesson1.md#Системы-управления-версиями-git) + - [Настройка окружения](lesson1.md#Настройка-окружения) + - [Насторойка проекта. Ветка HW1. Debug](lesson1.md#Насторойка-проекта-Ветка-hw1-debug) + +### Занятие 2 + - [Принципы ООП](lesson2.md#Принципы-ООП) + - [Структура памяти: куча, стек, регистры, константы](lesson2.md#Структура-памяти-куча-стек-регистры-константы) + - [Типы данных. Пакеты](lesson2.md#Типы-данных-Пакеты) + +### Занятие 3 + - [Объектная модель в Java](lesson3.md#Объектная-модель-в-java) + - [Сложность алгоритмов](lesson3.md#Сложность-алгоритмов) + +### Занятие 4 + - [Работа со строками](lesson4.md#Работа-со-строками) + - [Исключения](lesson4.md#Исключения) + - [Reflection. Аннотации. Модульное тестирование](lesson4.md#reflection-Аннотации-Модульное-тестирование) + +### Занятие 5 + - [Контейнеры/коллекции](lesson5.md#Контейнерыколлекции) + +### Занятие 6 + - [Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы](lesson6.md#iterator--iterable-Вложенные-внутренние-локальные-и-анонимные-классы) + - [Новое в Java 8](lesson6.md#Новое-в-java-8) + +### Занятие 7 + - [Параметризация. Стирание типов](lesson7.md#Параметризация-Стирание-типов) + - [Логирование](lesson7.md#Логирование) + - [Синглетон, Enum](lesson7.md#Синглетон-enum) + +### Занятие 8 + - [Работа с датами и временем](lesson8.md#Работа-с-датами-и-временем) + - [Работа с файлами и ресурсами](lesson8.md#Работа-с-файлами-и-ресурсами) + +### Занятие 9 + - [Ввод/вывод](lesson9.md#Вводвывод) + - [Сериализация](lesson9.md#Сериализация) + - [NIO](lesson9.md#nio) + - [Основы Java 8 Stream API](lesson9.md#Основы-java-8-stream-api) + +### Занятие 10 + - [Формат XML. Работа с XML в Java](lesson10.md#Формат-xml-Работа-с-xml-в-java) + - [JSON](lesson10.md#json) + - [DataInputStream / DataOutputStream](lesson10.md#datainputstream--dataoutputstream) + +### Занятие 11 + - [Многопоточность. Параллельное выполнение.](lesson11.md#Многопоточность-Параллельное-выполнение) + - [Потоки. Синхронизация](lesson11.md#Потоки-Синхронизация) + - [Ленивая инициализация, JMM](lesson11.md#Ленивая-инициализация-jmm) + +### Занятие 12 + - [java.util.concurrent](lesson12.md#javautilconcurrent) + +### Занятие 13 + - [Базы данных. Реляционные СУБД. PostgreSQL](lesson13.md#Базы-данных-Реляционные-СУБД-postgresql) + - [Конфигурирование данных в Java проекте](lesson13.md#Конфигурирование-данных-в-java-проекте) + - [Подключение DB в проект](lesson13.md#Подключение-db-в-проект) + +### Занятие 14 + - [JOIN](lesson14.md#join) + - [Транзакции](lesson14.md#Транзакции) + - [Установка/запуск Tomcat](lesson14.md#Установказапуск-tomcat) + +### Занятие 15 + - [HTML, Tomcat](lesson15.md#html-tomcat) + - [Сервлеты](lesson15.md#Сервлеты) + +### Занятие 16 + - [JSP](lesson16.md#jsp) + - [JSTL](lesson16.md#jstl) + +### Занятие 17 + - [Деплой в Heroku](lesson17.md#Деплой-в-heroku) + - [Classloader](lesson17.md#classloader) + - [Обзор Java Enterprise](lesson17.md#Обзор-java-enterprise) + diff --git a/intro.md b/intro.md new file mode 100644 index 0000000..c929bea --- /dev/null +++ b/intro.md @@ -0,0 +1,38 @@ + +# Вступительное занятие + +## Необходимое ПО +- JDK8 +- Git +- Аккаунт GitHub +- IntelliJ IDEA + +> Выбирать Ultimate, 30 days trial (нам понадобится Git, JavaScript, Tomcat, JSP). Учебный ключ выдается на первом занятии. + +## Рекомендуемые книги +- YAKOV FAIN: Программирование на Java для начинающих +- Книги по Java: от новичка до профессионала +- Джошуа Блох: Java. Эффективное программирование, 2-е издание +- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования +- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. + +## Ресуры в сети +- intuit: Программирование на Java +- Основы программирования на Java: учебное пособие + +## Вступительное задание +- Установите ПО: Git, Java 8, IntelliJ IDEA +- Создайте локальную копию нашего проекта: `git clone https://github.com/JavaWebinar/JavaSE-Web.git` +> в результате у вас должен появится каталог `JavaSE-Web` + +- В IntelliJ IDEA создайте новый проект, выбрав каталог `JavaSE-Web` + +![image](https://cloud.githubusercontent.com/assets/18701152/14917746/38c4a20a-0e29-11e6-8985-c57911da57c4.png) + +![image](https://cloud.githubusercontent.com/assets/18701152/14917800/71887238-0e29-11e6-9830-e557901892b4.png) + +![image](https://cloud.githubusercontent.com/assets/18701152/14917769/5025e29c-0e29-11e6-9c7b-70b82966ccbe.png) + +- Реализуйте класс `ArrayStorage`: хранение резюме на основе массива (методы `clear, get, save, delete, getAll, size`). +- Протестируйте вашу реализацию, запустив `MainTestArrayStorage.main()`: в IDEA слева на полях зеленая стрелка. +- Протестируйте вашу реализацию интерактивно с помощью `MainArray.main()`. diff --git a/lesson1.md b/lesson1.md new file mode 100644 index 0000000..0b1fc5c --- /dev/null +++ b/lesson1.md @@ -0,0 +1,60 @@ + +# Первое занятие + +## Разработка ПО. +- Книга: Мифический человеко-месяц +- Методологии разработки ПО +- Ещё раз про семь основных методологий разработки + +## Обзор инструментов и технологий. +- Обзор популярности инструментов и технологий Java за 2014г. +- Дополнительно: + - Автоматизированные сборки в Java + +## Обзор языка Java +- Java, JVM, JIT-компиляция + +![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) + +- Programming languages TIOBE Index +- ME, SE (русский), EE (русский) +- Oracle Java8 Home +- Дополнительно: + - Java version and vendor data analyzed + - Most Popular Java EE Servers + - Что такое Java? История создания + - Понимаем основы Java garbage collection + +## Системы управления версиями. Git. +- Система управления версиями. +- VCS/DVSC. + +![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) + +- Популярность разный VSC +- Книга по Git + +## Настройка окружения +- Idea Wiki (поставить кодировку UTF-8, поменять фонт по умолчанию на DejaVu) +- git занести в переменная окружения PATH, перезапустить cmd +- Создайте локальную копию нашего проекта: `git clone https://github.com/School-IT-Programm/resume-storage.git` +- Перейти в каталог проекта: `cd resume-storage` +- `git remote -v` +- `git remote set-url origin https://github.com/School-IT-Programm/resume-storage.git` - настройка pull +- `git remote set-url --push origin https://github.com/[YouGitHub/YourRepo].git` - настройка push +- `git push -u origin master` + +## Насторойка проекта. Ветка HW1. Debug +- Отладчик IntelliJ IDEA +- Эффективная работа с кодом в IntelliJ IDEA + +## Домашнее задание +- Модифицировать класс `ArrayStorage`: хранить все резюме в начале storage (без дырок null), чтобы не перебирать каждый раз все 10000 элементов. +``` +Хранеие резюме в storage (от 0 до size-1 элементов null нет): + +r1, r2, r3,..., rn, null, null,..., null +<---- size -----> +<---- storage.length ---------------> +``` +- Посмотреть на класс `Arrays`. Там есть полезные вещи, которые могут упростить код `ArrayStorage`. diff --git a/lesson10.md b/lesson10.md new file mode 100644 index 0000000..1c279e7 --- /dev/null +++ b/lesson10.md @@ -0,0 +1,19 @@ + +# Десятое занятие + +## Разбор Домашнего Задания-9: + +## Формат XML. Работа с XML в Java +- XML формат и технологии +- Wiki: XML, XSL , DOM, SAX, StAX, JAXB +- Работа с XML в Java. Реализация хранения в XML. + +## JSON +- JSON. JSON в JavaScript. REST +- Работа с JSON в Java: Google GSON и Jackson. Реализация хранения в JSON. + +## DataInputStream / DataOutputStream +- Реализация Store на основе `DataInputStream/DataOutputStream`. + +## Домашнее задание +- Сделать и протестировать реализацию `DataStreamSerializer` \ No newline at end of file diff --git a/lesson11.md b/lesson11.md new file mode 100644 index 0000000..1a1e7a9 --- /dev/null +++ b/lesson11.md @@ -0,0 +1,31 @@ + +# Одиннадцатое занятие + +## Многопоточность. Параллельное выполнение. +![Закон Мура](https://www.karlrupp.net/wp-content/uploads/2015/06/40-years-processor-trend.png) +- Закон Мура +- Закон Амдала + +![Concurrent vs Parallel](https://joearms.github.io/images/con_and_par.jpg) + +## Потоки. Синхронизация +- Потоки выполнения. Синхронизация. +- Методы wait(), notify(), notifyAll() класса Object + +## Ленивая инициализация, JMM +- Параллелизм в Java +- Реализация Singleton в JAVA +- Double checked locking +- Java Memory Model. final, volatile +- Initialization-on-demand holder idiom + +### Ресурсы +- Алексей Владыкин, Основы многопоточность в Java +- Виталий Чибриков, Java. Многопоточность +- Computer Science Center, курс Параллельное программирование +- Юрий Ткач, курс Advanced Java - Concurrency +- Головач, курс Java Multithreading + +## Домашнее задание +- Реализовать deadlock +- Взаимная блокировка diff --git a/lesson12.md b/lesson12.md new file mode 100644 index 0000000..c3a9900 --- /dev/null +++ b/lesson12.md @@ -0,0 +1,18 @@ + +# Двенадцатое занятие + +## Разбор Домашнего Задания-11: реализация dead lock. + +## java.util.concurrent +- Обзор java.util.concurrent.* +- Compare-and-swap +- Справочник по синхронизаторам java.util.concurrent.* +- Использование ThreadLocal переменных + +## Разбор домашнего задания 10го урока + +## Домашнее задание: +- Установить PostgreSQL +- Посомтреть на реляционные базы данных и SQL: + - Введение в базы данных + - Основы SQL \ No newline at end of file diff --git a/lesson13.md b/lesson13.md new file mode 100644 index 0000000..2ad74ff --- /dev/null +++ b/lesson13.md @@ -0,0 +1,29 @@ + +# Тринадцатое занятие + +### Базы данных. Реляционные СУБД. PostgreSQL +- DB-Engines Ranking +- Реляционная СУБД +- Введение в базы данных +- Реляционные базы vs NoSQL. SQL. Денормализация. PK, FK, Cascade +- PostgreSQL. Надёжность +- Создание базы резюме. Работа с базами данных из IDEA +- IDEA Database tools. + +### Конфигурирование данных в Java проекте +- Properties sample +- Конфигурирование DB и каталога хранения + +### Подключение DB в проект +- JDBC. JDBC Architecture. +- ConnectionFactory. Реализация SqlStorage. +- Ресурсы: + - Книга: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL + - Работа с базами данных с помощью JDBC драйвера + - Уроки по JDBC + +### ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW13 +- Доделать `SqlStorage` без контактов и секций. + - Для работы с DB надо в lib и проект добавить драйвер базы данных + - Запустить `SqlStorageTest` (в `AbstractStorageTest` контакты и секции закоменченны), креденшелы к базе взять из `Config` +- Вынести общий код (`getConnection(), prepareStatement, catch SQLException`) в класс `SqlHelper`. diff --git a/lesson14.md b/lesson14.md new file mode 100644 index 0000000..f625d1d --- /dev/null +++ b/lesson14.md @@ -0,0 +1,26 @@ + +# Четырнадцатое занятие + +### Разбор HW13 + +### JOIN +- LEFT, RIGHT, INNER JOIN +- Добавляем в `SqlStorage` контакты + +### Транзакции. +- Транзакция. ACID. Уровни изоляции транзакций. +- Уровни изоляции транзакций в SQL +- Добавляем в `SqlStorage` транзакции +- Batch execute. + +### Установка/запуск Tomcat +- Скачать и установить Tomcat 8. Устанавливать лучше простым копированием из архива в каталог (в том числе и для unix). Следите чтобы в пути не было пробелов и национальных букв. +- Для доступа к Tomсat Manager добавьте в конфигурацию Tomcat `TOMCAT_HOME\conf\tomcat-users.xml` права: +``` + +``` +- Запуск из `TOMCAT_HOME\bin\`: `catalina.bat start` + +## Домашнее задание HW14 +- Закончить реализацию `SqlStorage` с контактами +- Добавить `TextSection` в базу данных (`init_db.sql`) и `SqlStorage`. diff --git a/lesson15.md b/lesson15.md new file mode 100644 index 0000000..4939684 --- /dev/null +++ b/lesson15.md @@ -0,0 +1,26 @@ +# Пятнадцатое занятие + +### Разбор HW14 + +### HTML, Tomcat +- Протокол HTTP. Смотрим демо приложение в Chrome -> Инструменты разработчика +- Добавление в проект Web Facet. web.xml. Постороение/cтруктура WAR. Статические ресурсы. +- Настройка и деплой в Tomcat. Tomcat manager. +- Запуск Tomcat из IDEA. Динамическое обновление без передеплоя. + +### Сервлеты +- Создаем Servlet. Параметры. Кодировка. +- Дополнительно: + - How do servlets work? + - Язык программирования Java и среда NetBeans: Введение в сетевое программирование + - Основы работы с HTML + - Учебник HTML + - Технологии Java для разработки веб-приложений + - Таблицы стилей CSS + - Основы JavaScript + +## Домашнее задание HW15 +- Сделать реализацию `SqlStorage.getAll` через 2 отдельных запроса: отдельно резюме и отдельно контакты. +- Добавить в реализацию `SqlStorage` и в базу секции (кроме `OrganizationSection`). Для `ListSection` склеиваем строки через `\n`. +- Сделать отображение таблицы резюме в сервлете. + - HTML таблицы diff --git a/lesson16.md b/lesson16.md new file mode 100644 index 0000000..6e431f3 --- /dev/null +++ b/lesson16.md @@ -0,0 +1,21 @@ +# Шестнадцатое занятие + +### Разбор HW15 +- Почему вы никогда не должны использовать MongoDB +- Жизненный цикл сервлета +- Tomcat maxThreads configuration + +### JSP +- Что такое JSP. Wiki JSP +- Predefined Variables in JSP +- Стандартные элементы action +- How to use relative paths in JSP +- Отличие Redirect от Forward + +### JSTL +- JSTL +- JSTL для написания JSP страниц + +## Домашнее задание HW15 +- Доделать логику сервлета +- Дополнить отображение и редактирование JSP секциями diff --git a/lesson17.md b/lesson17.md new file mode 100644 index 0000000..e2cbc7c --- /dev/null +++ b/lesson17.md @@ -0,0 +1,24 @@ +# Семнадцатое занятие + +### Разбор HW16 + +### Деплой в Heroku +- Deployment with the Heroku CLI + +### Classloader +- Загрузка классов в Java +- Apache Tomcat Class Loader + +## Обзор Java Enterprise +- Из юниоров в разработчики: получаем первую работу +- Java Tools and Technologies Landscape for 2014 +- Java Tools and Technologies Landscape Report 2016 + +#### Spring Pet-Clinic +- Spring PetClinic Sample Application +- Demo +- Presentation + +#### Java Enterprise project Topjava +- Java Enterprise: Вводное занятие +- Demo приложение diff --git a/lesson2.md b/lesson2.md new file mode 100644 index 0000000..e5f3360 --- /dev/null +++ b/lesson2.md @@ -0,0 +1,37 @@ + +# Второе занятие + +## Принципы ООП. +- Методология процедурно-ориентированного и объектно-ориентированного программирования +- Объекты (cостояние, поведение, уникальность) +- Классы. Инкапсуляция. Наследование. Полиморфизм. +- Типы отношений между классами Наследование, агрегация, композиция, ассоциация. +- Достоинства/Недостатки ООП. Библиотеки vs фреймворки. +- Дополнительно: + - Что такое ООП и с чем его едят? + - Объектно ориентированное программирование + - Николай Алименков — Парадигмы ООП + - Концепции объектно-ориентированного программирования + +### Структура памяти: куча, стек, регистры, константы + - JVM изнутри - оптимизация и профилирование. + - Stack and Heap + - Дополнительно: + - Из каких частей состоит память java процесса. + - Permanent область памяти + - Java thread stack + - Размер Java объектов + +### Типы данных. Пакеты. + - Типы данных + - Классы- оберки + - Ссылочные типы + - Пакеты + - Модификаторы доступа. Область Видимости. + +## Домашнее задание +- Прочитать Соглашения по именованию. +- Реализовать `ArrayStorage.update` +- Сделать проверки: в `update/delete/get` - резюме есть в storage, в `save`- нет в storage: `System.out.println("Resume ...")`. +- Сделать в save проверку на переполнениеe: `System.out.println("...")`. +- Избавится от дублирования в коде `ArrayStorage` diff --git a/lesson3.md b/lesson3.md new file mode 100644 index 0000000..e86bcc0 --- /dev/null +++ b/lesson3.md @@ -0,0 +1,21 @@ + +# Третье занятие + +## Разбор Домашнего Задания-2 + +## Объектная модель в Java +- static +- Object. Контракт equals/hashCode +- Интерфейсы +- Полиморфизм, abstract + +## Сложность алгоритмов +- Алгоритмы и структуры данных для начинающих: сложность алгоритмов +- Time complexity +- Временная сложность алгоритма +- Вычислительная сложность +- Шаблонный метод + +## Домашнее задание +- Закончить реализацию `AbstractArrayStorage`, `ArrayStorage`, `SortedArrayStorage` (`SortedArrayStorage` хранит элементы отсортированными, сортировать весь массив не надо). +- Сделать проверку `ArrayStorage.update` diff --git a/lesson4.md b/lesson4.md new file mode 100644 index 0000000..4207304 --- /dev/null +++ b/lesson4.md @@ -0,0 +1,28 @@ + +# Четвертое занятие + +## Разбор Домашнего Задания-3 + +## Работа со строками. +- Строки в Java. Кодировка. +- Управление строками, функции для работы со строками в Java. +- StringBuilder vs StringBuffer +- String literal pool + +## Исключения + - Исключения (Exceptions). + - "Java. Эффективное программирование" Джошуа Блох: Исключения. + - Конструктор. this, super + +![image](https://cloud.githubusercontent.com/assets/18701152/15581283/4c2f5348-2374-11e6-8fd2-e4de02d2c389.png) + +## Reflection. Аннотации. Модульное тестирование + - Аннотации + - Введение в Java Reflection API + - Модульное тестирование JUnit 4 + - Тестирование с помощью JUnit (Test Case) + + +## Домашнее задание +Реализовать `AbstractStorageTest` и тесты `ArrayStorageTest` и `SortedArrayStorageTest`. +В `MainReflection` сделать вызов метода `toString` через отражение. diff --git a/lesson5.md b/lesson5.md new file mode 100644 index 0000000..fdc77b0 --- /dev/null +++ b/lesson5.md @@ -0,0 +1,13 @@ + +# Пятое занятие + +## Разбор Домашнего Задания-4 + +## Контейнеры/коллекции. +- List, Set, Map, Queue, Iterator, ListIterator +- Структуры данных в картинках +- Инициализация полей в Java +- Java собеседование по коллекциям + +## Домашнее задание +Выделить общий класс `AbstractStorage` и реализовать подклассы `ListStorage` и `MapStorage`. Выбор реализации List и Map за вами. \ No newline at end of file diff --git a/lesson6.md b/lesson6.md new file mode 100644 index 0000000..3295fbb --- /dev/null +++ b/lesson6.md @@ -0,0 +1,20 @@ + +# Шестое занятие + +## Разбор Домашнего Задания-5 +- Преобразования Integer и int + +## Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы. +- Iterator / Iterable. +- Вложенные и внутренние классы. Примеры в Collections API: Arrays.asList, ArrayList.iterator +- Локальные и анонимные классы. Comparator + +## Новое в Java 8. +- Lambda выражения. Default методы для Interface. +- Встроенные функциональные интерфейсы. + +## Домашнее задание +- Сделать рефакторинг тестов: `saveOverflow` должно быть только для Array реализаций. +- Рефакторинг: в конструктор Resume добавить второй параметр `fullName` +- Сделать рефакторинг всех реализаций `Storage`: заменить метод `Resume[] getAll()` на `List getAllSorted()` +- Реализовать до конца `MapUuidStorage`. Подумать что еще может быть search key в реализации на основе Map. diff --git a/lesson7.md b/lesson7.md new file mode 100644 index 0000000..30494c9 --- /dev/null +++ b/lesson7.md @@ -0,0 +1,46 @@ + +# Седьмое занятие + +## [Разбор Домашнего Задания-6](lesson6.md#Домашнее-задание) + +## Параметризация. Стирание типов. +- Дженерики (Java, обучающая статья) +- Обобщения (Generic) +- Ограничения. + +## Логирование +- Log4J (Apache logging) +- Java Logging API - Tutorial +- Логирование в Java / quick start +- Ведение лога приложения +- Java Logging: история кошмара + +## Синглетон, Enum +- Одиночка (шаблон проектирования) +- Перечисляемые типы (enum) в Java + +## Домашнее задание: +Доменный объект + +Cделать объектную модель резюме (диаграмма и классы). Образец резюме (делаем упрощенно) + - Делать только классы, включаемые в Resume. Resume - главный класс. В него все включается (композиция - строгий вид агрегации). + - Схожие по структуре и функциональности сущности делаем одним классом. + - Модель упрощаем для хранения только необходимой информации для вывода/ редактирования резюме. + - В модели резюме должны быть представлены контакты и следующие разделы: + - PERSONAL("Личные качества") + - OBJECTIVE("Позиция") + - ACHIEVEMENT("Достижения") + - QUALIFICATIONS("Квалификация") + - EXPERIENCE("Опыт работы") + - EDUCATION("Образование") + - В секциях Достижения и Квалификация хранить список строк + - Учесть в классах модели, что обработка резюме (вывод в html, сохранение, чтение) будет сделано следующим образом: +обработка `fullName`, цикл обработки по контактам, цикл обработки по секциям (для секций использовать полиморфизм, как для фигур: круг, квадрат..). +При добавлении/удалении новых видов контактов (например домашний телефон) или разделов изменения в коде (и БД) должны быть минимальны. + +#### Инструменты для рисования: + +- Generate class diagram in IntelliJ IDEA (Help: working with Diagrams) +- Нарисовать и сфотографировать +- Online: www.draw.io +- yEd - Graph Editor diff --git a/lesson8.md b/lesson8.md new file mode 100644 index 0000000..d7336ad --- /dev/null +++ b/lesson8.md @@ -0,0 +1,21 @@ + +# Восьмое занятие + +## Разбор Домашнего Задания-7: объектная модель резюме + +## Работа с датами и временем +- Класс Date, Calendar, TimeZone +- Java – Convert date and time between timezone +- Joda Time library +- Java 8 Date API + +## Работа с файлами и ресурсами. + - File. Работа с файловой системой. + - Работа с ресурсами. Правильно освобождаем ресурсы в Java + - Java 7 try-with-resources + +## Домашнее задание +- Переделать модель резюме: учесть, что на одной работе (в одном учебном заведении) можно работать/ учиться в разные периоды и при этом имя организации не дублируется +- Сделать рекурсивный обход и вывод имени файлов в каталогах и подкаталогах (корневой каталог- ваш проект) +- Заполнить в `AbstractStorageTest` резюме данными +- Реализовать `AbstractFileStorage`, базовый класс для хранения резюме в файлах. diff --git a/lesson9.md b/lesson9.md new file mode 100644 index 0000000..de787f6 --- /dev/null +++ b/lesson9.md @@ -0,0 +1,25 @@ + +# Девятое занятие + +## Разбор Домашнего Задания-8: + +## Ввод/вывод +- Пакет java.io +- Паттерн Декоратор. +- Классы Reader и Writer. + +## Сериализация +- Сериализация объектов (serialization) +- Реализация Storage используя сериализацию. + +## NIO +- NIO Java 7 +- Чтения строк из файла + +## Основы Java 8 Stream API +- Потоки + +## Домашнее задание +- Сделать рекурсивный вывод каталогов с отступом +- Реализовать Storage через java.nio.file.Path. +- Сделать возможным выбор меджу FileStorage и PathStorage для сериализации через ObjectStream. diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java new file mode 100644 index 0000000..7aff038 --- /dev/null +++ b/src/ArrayStorage.java @@ -0,0 +1,30 @@ +/** + * Array based storage for Resumes + */ +public class ArrayStorage { + Resume[] storage = new Resume[10000]; + + void clear() { + } + + void save(Resume r) { + } + + Resume get(String uuid) { + return null; + } + + void delete(String uuid) { + } + + /** + * @return array, contains only Resumes in storage (without null) + */ + Resume[] getAll() { + return new Resume[0]; + } + + int size() { + return 0; + } +} diff --git a/src/MainArray.java b/src/MainArray.java new file mode 100644 index 0000000..20f1f14 --- /dev/null +++ b/src/MainArray.java @@ -0,0 +1,70 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * Test for com.urise.webapp.storage.ArrayStorage + */ +public class MainArray { + private final static ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + + public static void main(String[] args) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + Resume r; + while (true) { + System.out.print("Введите одну из команд - (list | save uuid | delete uuid | get uuid | clear | exit): "); + String[] params = reader.readLine().trim().toLowerCase().split(" "); + if (params.length < 1 || params.length > 2) { + System.out.println("Неверная команда."); + continue; + } + String uuid = null; + if (params.length == 2) { + uuid = params[1].intern(); + } + switch (params[0]) { + case "list": + printAll(); + break; + case "size": + System.out.println(ARRAY_STORAGE.size()); + break; + case "save": + r = new Resume(); + r.uuid = uuid; + ARRAY_STORAGE.save(r); + printAll(); + break; + case "delete": + ARRAY_STORAGE.delete(uuid); + printAll(); + break; + case "get": + System.out.println(ARRAY_STORAGE.get(uuid)); + break; + case "clear": + ARRAY_STORAGE.clear(); + printAll(); + break; + case "exit": + return; + default: + System.out.println("Неверная команда."); + break; + } + } + } + + static void printAll() { + Resume[] all = ARRAY_STORAGE.getAll(); + System.out.println("----------------------------"); + if (all.length == 0) { + System.out.println("Empty"); + } else { + for (Resume r : all) { + System.out.println(r); + } + } + System.out.println("----------------------------"); + } +} \ No newline at end of file diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java new file mode 100644 index 0000000..17ba8c0 --- /dev/null +++ b/src/MainTestArrayStorage.java @@ -0,0 +1,39 @@ +/** + * Test for com.urise.webapp.storage.ArrayStorage + */ +public class MainTestArrayStorage { + static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + + public static void main(String[] args) { + Resume r1 = new Resume(); + r1.uuid = "uuid1"; + Resume r2 = new Resume(); + r2.uuid = "uuid2"; + Resume r3 = new Resume(); + r3.uuid = "uuid3"; + + ARRAY_STORAGE.save(r1); + ARRAY_STORAGE.save(r2); + ARRAY_STORAGE.save(r3); + + System.out.println("Get r1: " + ARRAY_STORAGE.get(r1.uuid)); + System.out.println("Size: " + ARRAY_STORAGE.size()); + + System.out.println("Get dummy: " + ARRAY_STORAGE.get("dummy")); + + printAll(); + ARRAY_STORAGE.delete(r1.uuid); + printAll(); + ARRAY_STORAGE.clear(); + printAll(); + + System.out.println("Size: " + ARRAY_STORAGE.size()); + } + + static void printAll() { + System.out.println("\nGet All"); + for (Resume r : ARRAY_STORAGE.getAll()) { + System.out.println(r); + } + } +} diff --git a/src/Resume.java b/src/Resume.java new file mode 100644 index 0000000..937c6a7 --- /dev/null +++ b/src/Resume.java @@ -0,0 +1,13 @@ +/** + * com.urise.webapp.model.Resume class + */ +public class Resume { + + // Unique identifier + String uuid; + + @Override + public String toString() { + return uuid; + } +} From fce21c954f34d0037e4ae1f3f469bd4fc4c90ab1 Mon Sep 17 00:00:00 2001 From: "admin@javaops.ru" Date: Thu, 19 Jul 2018 23:34:48 +0300 Subject: [PATCH 02/71] Update lessons and classes --- README.md | 146 ++++++++++++++++++------------ intro.md | 38 -------- lesson/lesson1.md | 116 ++++++++++++++++++++++++ lesson10.md => lesson/lesson10.md | 0 lesson11.md => lesson/lesson11.md | 0 lesson12.md => lesson/lesson12.md | 19 +++- lesson13.md => lesson/lesson13.md | 0 lesson14.md => lesson/lesson14.md | 0 lesson15.md => lesson/lesson15.md | 0 lesson16.md => lesson/lesson16.md | 0 lesson17.md => lesson/lesson17.md | 0 lesson2.md => lesson/lesson2.md | 4 + lesson3.md => lesson/lesson3.md | 3 + lesson4.md => lesson/lesson4.md | 0 lesson5.md => lesson/lesson5.md | 4 +- lesson6.md => lesson/lesson6.md | 0 lesson7.md => lesson/lesson7.md | 0 lesson8.md => lesson/lesson8.md | 0 lesson9.md => lesson/lesson9.md | 0 lesson1.md | 60 ------------ src/MainArray.java | 3 +- src/MainTestArrayStorage.java | 2 +- src/Resume.java | 2 +- 23 files changed, 237 insertions(+), 160 deletions(-) delete mode 100644 intro.md create mode 100644 lesson/lesson1.md rename lesson10.md => lesson/lesson10.md (100%) rename lesson11.md => lesson/lesson11.md (100%) rename lesson12.md => lesson/lesson12.md (63%) rename lesson13.md => lesson/lesson13.md (100%) rename lesson14.md => lesson/lesson14.md (100%) rename lesson15.md => lesson/lesson15.md (100%) rename lesson16.md => lesson/lesson16.md (100%) rename lesson17.md => lesson/lesson17.md (100%) rename lesson2.md => lesson/lesson2.md (92%) rename lesson3.md => lesson/lesson3.md (87%) rename lesson4.md => lesson/lesson4.md (100%) rename lesson5.md => lesson/lesson5.md (62%) rename lesson6.md => lesson/lesson6.md (100%) rename lesson7.md => lesson/lesson7.md (100%) rename lesson8.md => lesson/lesson8.md (100%) rename lesson9.md => lesson/lesson9.md (100%) delete mode 100644 lesson1.md diff --git a/README.md b/README.md index 8680649..e288257 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,120 @@ -# Курс JavaSE + Web - -## Вступительное заниятие - - [Необходимое ПО](intro.md#Необходимое-ПО) - - [Рекомендуемые книги](intro.md#Рекомендуемые-книги) - - [Ресуры в сети](intro.md#Ресуры-в-сети) - - [Вступительное задание](intro.md#Вступительное-задание) - -## Темы курса -### Занятие 1 - - [Разработка ПО](lesson1.md#Разработка-ПО) - - [Обзор языка Java](lesson1.md#Обзор-языка-java) - - [Системы управления версиями. Git](lesson1.md#Системы-управления-версиями-git) - - [Настройка окружения](lesson1.md#Настройка-окружения) - - [Насторойка проекта. Ветка HW1. Debug](lesson1.md#Насторойка-проекта-Ветка-hw1-debug) +# Курс BaseJava (обновленный и переработанный) + +## Разработка Web приложения "База данных резюме" + - используем: Java 8, IntelliJ IDEA, + GitHib/Git, Сервлеты, JSP, JSTL, Tomcat, JUnit, PostgreSQL, GSON, JAXB + - хранение резюме + - в памяти на основе массива, отсортированного массива, списка и ассоциированного массива (Map) + - в файловой системе (File API и Java 7 NIO File API) + - в стандартной и кастомной сериализации Java + - в формате JSON (Google Gson) + - в формате XML (JAXB) + - в реляционной базе PostgreSQL + - деплой веб приложения + - в контейнер сервлетов Tomcat + - в облачный сервис Heroku + +Приложение будет разрабатываться начиная со первого занятия, основываясь на базовых темах курса: +**объектная модель, коллекции, система ввода-вывода, работа с файлами, сериализация, работа с XML, JSON, SQL, персистентность в базу данных (PostgreSQL), сервлеты, HTML/JSP/JSTL, веб-контейнер Tomcat, модульные тесты JUnit, java.util.Logging, система контроля версий Git.** + +> Любое знание стоит воспринимать как подобие семантического дерева: убедитесь в том, что понимаете фундаментальные принципы, то есть ствол и крупные ветки, прежде чем лезть в мелкие листья-детали. Иначе последним не на чем будет держаться. + +[*— Илон Маск](https://ru.wikipedia.org/wiki/Маск,_Илон) + +# Изучайте [первое открытое занятие](lesson/lesson1.md). +### Внизу урока есть первое домашнее задание, по которому можно оценить свой уровень готовности к проекту. + +## Программа +### [Регистрация](http://javaops.ru/reg/basejava) +### Открытое занятие 1 + - [Презентация проекта](lesson/lesson1.md#-Вебинар-ПРЕЗЕНТАЦИЯ-обучения) + - [Разработка ПО](lesson/lesson1.md#-1-Разработка-ПО) + - [Обзор языка Java](lesson/lesson1.md#-3-Обзор-языка-java) + - [Системы управления версиями. Git](lesson/lesson1.md#-4-Системы-управления-версиями-git) + - [ПЕРВОЕ ДОМАШНЕЕ ЗАДАНИЕ](lesson/lesson1.md#Домашнее-задание-hw1) ### Занятие 2 - - [Принципы ООП](lesson2.md#Принципы-ООП) - - [Структура памяти: куча, стек, регистры, константы](lesson2.md#Структура-памяти-куча-стек-регистры-константы) - - [Типы данных. Пакеты](lesson2.md#Типы-данных-Пакеты) + - [Принципы ООП](lesson/lesson2.md#Принципы-ООП) + - [Структура памяти: куча, стек, регистры, константы](lesson/lesson2.md#Структура-памяти-куча-стек-регистры-константы) + - [Типы данных. Пакеты](lesson/lesson2.md#Типы-данных-Пакеты) ### Занятие 3 - - [Объектная модель в Java](lesson3.md#Объектная-модель-в-java) - - [Сложность алгоритмов](lesson3.md#Сложность-алгоритмов) - + - [Объектная модель в Java](lesson/lesson3.md#Объектная-модель-в-java) + - [Сложность алгоритмов](lesson/lesson3.md#Сложность-алгоритмов) + - [Паттерн проектирования Шаблонный метод](https://github.com/JavaOPs/JavaSE-Web/blob/master/lesson/lesson3.md#Паттерн-проектирования-Шаблонный-метод) + ### Занятие 4 - - [Работа со строками](lesson4.md#Работа-со-строками) - - [Исключения](lesson4.md#Исключения) - - [Reflection. Аннотации. Модульное тестирование](lesson4.md#reflection-Аннотации-Модульное-тестирование) + - [Работа со строками](lesson/lesson4.md#Работа-со-строками) + - [Исключения](lesson/lesson4.md#Исключения) + - [Reflection. Аннотации. Модульное тестирование](lesson/lesson4.md#reflection-Аннотации-Модульное-тестирование) ### Занятие 5 - - [Контейнеры/коллекции](lesson5.md#Контейнерыколлекции) + - [Контейнеры/коллекции](lesson/lesson5.md#Контейнерыколлекции) ### Занятие 6 - - [Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы](lesson6.md#iterator--iterable-Вложенные-внутренние-локальные-и-анонимные-классы) - - [Новое в Java 8](lesson6.md#Новое-в-java-8) + - [Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы](lesson/lesson6.md#iterator--iterable-Вложенные-внутренние-локальные-и-анонимные-классы) + - [Новое в Java 8](lesson/lesson6.md#Новое-в-java-8) ### Занятие 7 - - [Параметризация. Стирание типов](lesson7.md#Параметризация-Стирание-типов) - - [Логирование](lesson7.md#Логирование) - - [Синглетон, Enum](lesson7.md#Синглетон-enum) + - [Параметризация. Стирание типов](lesson/lesson7.md#Параметризация-Стирание-типов) + - [Логирование](lesson/lesson7.md#Логирование) + - [Синглетон, Enum](lesson/lesson7.md#Синглетон-enum) ### Занятие 8 - - [Работа с датами и временем](lesson8.md#Работа-с-датами-и-временем) - - [Работа с файлами и ресурсами](lesson8.md#Работа-с-файлами-и-ресурсами) + - [Работа с датами и временем](lesson/lesson8.md#Работа-с-датами-и-временем) + - [Работа с файлами и ресурсами](lesson/lesson8.md#Работа-с-файлами-и-ресурсами) ### Занятие 9 - - [Ввод/вывод](lesson9.md#Вводвывод) - - [Сериализация](lesson9.md#Сериализация) - - [NIO](lesson9.md#nio) - - [Основы Java 8 Stream API](lesson9.md#Основы-java-8-stream-api) + - [Ввод/вывод](lesson/lesson9.md#Вводвывод) + - [Сериализация](lesson/lesson9.md#Сериализация) + - [NIO](lesson/lesson9.md#nio) + - [Основы Java 8 Stream API](lesson/lesson9.md#Основы-java-8-stream-api) ### Занятие 10 - - [Формат XML. Работа с XML в Java](lesson10.md#Формат-xml-Работа-с-xml-в-java) - - [JSON](lesson10.md#json) - - [DataInputStream / DataOutputStream](lesson10.md#datainputstream--dataoutputstream) + - [Формат XML. Работа с XML в Java](lesson/lesson10.md#Формат-xml-Работа-с-xml-в-java) + - [JSON](lesson/lesson10.md#json) + - [DataInputStream / DataOutputStream](lesson/lesson10.md#datainputstream--dataoutputstream) ### Занятие 11 - - [Многопоточность. Параллельное выполнение.](lesson11.md#Многопоточность-Параллельное-выполнение) - - [Потоки. Синхронизация](lesson11.md#Потоки-Синхронизация) - - [Ленивая инициализация, JMM](lesson11.md#Ленивая-инициализация-jmm) + - [Многопоточность. Параллельное выполнение.](lesson/lesson11.md#Многопоточность-Параллельное-выполнение) + - [Потоки. Синхронизация](lesson/lesson11.md#Потоки-Синхронизация) + - [Ленивая инициализация, JMM](lesson/lesson11.md#Ленивая-инициализация-jmm) ### Занятие 12 - - [java.util.concurrent](lesson12.md#javautilconcurrent) + - [java.util.concurrent](lesson/lesson12.md#javautilconcurrent) ### Занятие 13 - - [Базы данных. Реляционные СУБД. PostgreSQL](lesson13.md#Базы-данных-Реляционные-СУБД-postgresql) - - [Конфигурирование данных в Java проекте](lesson13.md#Конфигурирование-данных-в-java-проекте) - - [Подключение DB в проект](lesson13.md#Подключение-db-в-проект) + - [Базы данных. Реляционные СУБД. PostgreSQL](lesson/lesson13.md#Базы-данных-Реляционные-СУБД-postgresql) + - [Конфигурирование данных в Java проекте](lesson/lesson13.md#Конфигурирование-данных-в-java-проекте) + - [Подключение DB в проект](lesson/lesson13.md#Подключение-db-в-проект) ### Занятие 14 - - [JOIN](lesson14.md#join) - - [Транзакции](lesson14.md#Транзакции) - - [Установка/запуск Tomcat](lesson14.md#Установказапуск-tomcat) + - [JOIN](lesson/lesson14.md#join) + - [Транзакции](lesson/lesson14.md#Транзакции) + - [Установка/запуск Tomcat](lesson/lesson14.md#Установказапуск-tomcat) ### Занятие 15 - - [HTML, Tomcat](lesson15.md#html-tomcat) - - [Сервлеты](lesson15.md#Сервлеты) + - [HTML, Tomcat](lesson/lesson15.md#html-tomcat) + - [Сервлеты](lesson/lesson15.md#Сервлеты) ### Занятие 16 - - [JSP](lesson16.md#jsp) - - [JSTL](lesson16.md#jstl) + - [JSP](lesson/lesson16.md#jsp) + - [JSTL](lesson/lesson16.md#jstl) ### Занятие 17 - - [Деплой в Heroku](lesson17.md#Деплой-в-heroku) - - [Classloader](lesson17.md#classloader) - - [Обзор Java Enterprise](lesson17.md#Обзор-java-enterprise) - + - [Деплой в Heroku](lesson/lesson17.md#Деплой-в-heroku) + - [Classloader](lesson/lesson17.md#classloader) + - [Обзор Java Enterprise](lesson/lesson17.md#Обзор-java-enterprise) + +## Рекомендуемые книги +- YAKOV FAIN: Программирование на Java для начинающих +- Книги по Java: от новичка до профессионала +- Джошуа Блох: Java. Эффективное программирование, 2-е издание +- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования +- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. + +## Ресуры в сети +- [Руководство по Java Core](http://proselyte.net/tutorials/java-core/) +- [Java. Базовый курс](https://stepik.org/course/Java-Базовый-курс-187) +- intuit: Программирование на Java +- Основы программирования на Java: учебное пособие diff --git a/intro.md b/intro.md deleted file mode 100644 index c929bea..0000000 --- a/intro.md +++ /dev/null @@ -1,38 +0,0 @@ - -# Вступительное занятие - -## Необходимое ПО -- JDK8 -- Git -- Аккаунт GitHub -- IntelliJ IDEA - -> Выбирать Ultimate, 30 days trial (нам понадобится Git, JavaScript, Tomcat, JSP). Учебный ключ выдается на первом занятии. - -## Рекомендуемые книги -- YAKOV FAIN: Программирование на Java для начинающих -- Книги по Java: от новичка до профессионала -- Джошуа Блох: Java. Эффективное программирование, 2-е издание -- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования -- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. - -## Ресуры в сети -- intuit: Программирование на Java -- Основы программирования на Java: учебное пособие - -## Вступительное задание -- Установите ПО: Git, Java 8, IntelliJ IDEA -- Создайте локальную копию нашего проекта: `git clone https://github.com/JavaWebinar/JavaSE-Web.git` -> в результате у вас должен появится каталог `JavaSE-Web` - -- В IntelliJ IDEA создайте новый проект, выбрав каталог `JavaSE-Web` - -![image](https://cloud.githubusercontent.com/assets/18701152/14917746/38c4a20a-0e29-11e6-8985-c57911da57c4.png) - -![image](https://cloud.githubusercontent.com/assets/18701152/14917800/71887238-0e29-11e6-9830-e557901892b4.png) - -![image](https://cloud.githubusercontent.com/assets/18701152/14917769/5025e29c-0e29-11e6-9c7b-70b82966ccbe.png) - -- Реализуйте класс `ArrayStorage`: хранение резюме на основе массива (методы `clear, get, save, delete, getAll, size`). -- Протестируйте вашу реализацию, запустив `MainTestArrayStorage.main()`: в IDEA слева на полях зеленая стрелка. -- Протестируйте вашу реализацию интерактивно с помощью `MainArray.main()`. diff --git a/lesson/lesson1.md b/lesson/lesson1.md new file mode 100644 index 0000000..3e8a4f3 --- /dev/null +++ b/lesson/lesson1.md @@ -0,0 +1,116 @@ +# Первое занятие + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар-презентация обучения на проекте BaseJava](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) +#### [Итоговый пример приложения, разрабатываемого в рамках данного курса (на примере резюме Григория Кислина)](https://javawebinar.github.io/) + +### Подготовка рабочего окружения +- Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) +- Установите систему управления версиями [Git](http://git-scm.com/downloads) (опции по умолчанию) +- Создайте аккаунт на [GitHub](https://github.com/). Для удобной навигации по файлам на GitHub можно установить расширение для браузера [Octotree](https://habrahabr.ru/post/223527/) +- Установите [IntelliJ IDEA](http://www.jetbrains.com/idea/download/index.html). **Пока нет базы данных и веб, можно работать с версией Community**. На версию Ultimate дается 30 дней пробного бесплатного использования (trial). На проектах каждый участник проектов получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев. + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) +- [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) +- [Размеры проектов в количестве строк кода [eng]](https://medium.freecodecamp.com/the-biggest-codebases-in-history-a128bb3eea73) +- [Соглашения по оформлению кода [eng]](https://google.github.io/styleguide/javaguide.html) +- [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) +- [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) +- [Bash — шпаргалка для начинающих](https://tproger.ru/translations/bash-cheatsheet) +- [Интерактивный курс по SQL](http://www.sql-ex.ru/) +- [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) +- **Обновление!!**[Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) + - [Java Tools and Technologies Landscape Report 2016](https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/) + - [Java Tools and Technologies Landscape for 2014](http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014) +- **Дополнительно:** + - [Автоматизированная сборка проекта в Java](http://spring-projects.ru/guides/maven/) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) +- [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) (wiki) +- [Что такое Java? История создания](http://www.intuit.ru/studies/courses/16/16/lecture/27105) +- [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) + +![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) + +- [ME](http://ru.wikipedia.org/wiki/Java_Platform,_Micro_Edition), [SE](https://ru.wikipedia.org/wiki/Java_Platform,_Standard_Edition), [EE](http://ru.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) (wiki) +- [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh/) (используем на курсе [MasterJava](https://github.com/JavaWebinar/masterjava#Занятие-2)) +- [Oracle Java8 Home](http://docs.oracle.com/javase/8/docs/index.html) +- **Дополнительно:** + - [Java version and vendor data analyzed 2017](https://plumbr.io/blog/java/java-version-and-vendor-data-analyzed-2017-edition) + - [Most popular Java application servers: 2017 edition](https://plumbr.io/blog/java/most-popular-java-application-servers-2017-edition) + - [Понимаем основы Java garbage collection](https://ggenikus.github.io/blog/2014/05/04/gc) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) + +![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) + + - [Система управления версиями](https://ru.wikipedia.org/wiki/Система_управления_версиями) (wiki) + - [Сравнение разных VCS](https://biz30.timedoctor.com/ru/cистема-контроля-версий/) + - [Git обучалка](https://githowto.com/ru) + - [Интерактивная Git обучалка (в настройках выберите русский язык)](http://learngitbranching.js.org) + - [Официальная книга про Git](https://git-scm.com/book/ru/v2) + - [Working with remote repositories](https://illustrated-git.readthedocs.org/en/latest/#working-with-remote-repositories) + - [Базовый курс по обучению Git](https://www.youtube.com/playlist?list=PLIU76b8Cjem5B3sufBJ_KFTpKkMEvaTQR) (youtube) + - [Git. Быстрый старт](https://www.youtube.com/watch?v=4-NX17Ip-xQ&list=PLmRNNqEA7JoM77hOJkPrLOfJQGizCLR3P) (youtube) + +### Настройка проекта +- Создайте на GitHub репозиторий с названием `basejava` +- Откройте консоль (терминал) у себя на компьютере +- Наберите и запустите: `git` (по умолчанию при установке git заносится в PATH. Если он не находится, [занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль) +- Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` +- Перейдите в каталог проекта: `cd basejava` +- Настройте git в локальном проекте на свой проект в GitHub: + - `git remote -v` + - `git remote set-url origin url_на_твой_basejava-репозиторий.git` - настройка pull + - `git remote set-url --push origin url_на_твой_basejava-репозиторий.git` - настройка push + - `git push -u origin master` + +## Домашнее задание HW1 +- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, который вы клонировали ранее к себе на компьютер: + +![newproject](https://user-images.githubusercontent.com/29703461/38273513-d1f7ce52-3794-11e8-829c-305212c25be7.png) + +![next](https://user-images.githubusercontent.com/29703461/38273546-e712a6fe-3794-11e8-9850-29287b46a8a0.png) + +![next1](https://user-images.githubusercontent.com/29703461/38273584-00e07dc2-3795-11e8-9006-3109f949cf33.png) + +![finish](https://user-images.githubusercontent.com/29703461/38275669-3e621614-379b-11e8-8b3a-8e0a3ad4c65c.png) + +- Реализуйте класс `ArrayStorage`, организовав хранение резюме на основе массива с методами `save, get, delete, size, clear, getAll` +- Храните все резюме в начале `storage` (без дырок в виде `null`), чтобы не перебирать каждый раз все 10000 элементов +``` +Схема хранения резюме в массиве storage (в элементах от 0 до size-1 отсутствуют null): + +r1, r2, r3,..., rn, null, null,..., null +<----- size -----> +<------- storage.length (10000) -------> +``` +- Посмотрите на класс `java.util.Arrays`. В нем есть полезные методы, которые помогут вам написать более простой и понятный код +- Протестируйте вашу реализацию с помощью классов `MainArray.main()` и `MainTestArrayStorage.main()` +- Изучите дополнительные материалы по IntelliJ IDEA: + - [Idea Wiki](https://github.com/JavaOPs/topjava/wiki/IDEA) ([поставьте кодировку UTF-8](https://github.com/JavaOPs/topjava/wiki/IDEA#Поставить-кодировку-utf-8), [поменяйте шрифт по умолчанию на DejaVu](https://github.com/JavaOPs/topjava/wiki/IDEA#Поменять-фонт-по-умолчанию-dejavu)) + - [Руководство пользователя IntelliJ IDEA. Отладчик](http://info.javarush.ru/idea_help/2014/01/22/Руководство-пользователя-IntelliJ-IDEA-Отладчик-.html) + - [Эффективная работа с кодом в IntelliJ IDEA](https://www.youtube.com/watch?v=tpv5n2jWHlw) (youtube) + - [Эффективная работа в IDEA](https://www.youtube.com/watch?v=_rj7dx6c5R8) (youtube) + +### Вопросы по HW1 + > Не могу запустить программу, да и рядом с классами появился какой-то значок + ![badsrc](https://user-images.githubusercontent.com/29703461/38277015-9cd9155e-379f-11e8-9cd4-a9182a005e9a.png) + - Проблема в том, что IDEA неправильно "воспринимает" папку `src`. Для ее решения необходимо нажать `ПКМ на папке src -> выбрать Mark Directory as -> Sources Root` + + > Что такое `null`? + +[Что такое null в Java?](http://qaru.site/questions/1960/what-is-null-in-java) (оригинал: [What is null in Java? +](https://stackoverflow.com/questions/2707322/what-is-null-in-java)) + +### Замечания по выполнению HW1 +1. Все резюме в хранилище имеют уникальный `uuid`, что исключает повторы. Cортировка по `uuid` не требуется +2. Давайте осмысленные комментарии коммитам +3. Перед каждым коммитом не забывайте пользоваться сочетанием клавиш `Ctrl + Alt + L` (автоматическое форматирование кода) +4. Не злоупотребляйте пустыми строками. Они используются нечасто для логического отделения больших кусков кода. +5. Удаляйте неиспользуемые импорты (`Ctrl + Alt + O`) +5. Не игнорируй подсказки IDEA (подсвечивает) +6. `Resume r` — давай переменным осмысленные имена, например `resume`. `r` допустимо в коротких циклах и лямбдах. +7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового +8. По заданию необходимо посмотреть в классе `Arrays методы`, которые помогут упростить реализацию ваших методов `clear()` и `getAll()` diff --git a/lesson10.md b/lesson/lesson10.md similarity index 100% rename from lesson10.md rename to lesson/lesson10.md diff --git a/lesson11.md b/lesson/lesson11.md similarity index 100% rename from lesson11.md rename to lesson/lesson11.md diff --git a/lesson12.md b/lesson/lesson12.md similarity index 63% rename from lesson12.md rename to lesson/lesson12.md index c3a9900..47156cd 100644 --- a/lesson12.md +++ b/lesson/lesson12.md @@ -9,10 +9,27 @@ - Справочник по синхронизаторам java.util.concurrent.* - Использование ThreadLocal переменных +> Замечания по видео: + + ThreadLocal DATE_FORMAT = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + }; + }; + +можно написать через лямбду: + + ThreadLocal.withInitial(() -> new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")); + +А лучше использовать потокобезопасный `DateTimeFormatter` Java 8 Time API: + + DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); + ## Разбор домашнего задания 10го урока ## Домашнее задание: - Установить PostgreSQL - Посомтреть на реляционные базы данных и SQL: - Введение в базы данных - - Основы SQL \ No newline at end of file + - Основы SQL diff --git a/lesson13.md b/lesson/lesson13.md similarity index 100% rename from lesson13.md rename to lesson/lesson13.md diff --git a/lesson14.md b/lesson/lesson14.md similarity index 100% rename from lesson14.md rename to lesson/lesson14.md diff --git a/lesson15.md b/lesson/lesson15.md similarity index 100% rename from lesson15.md rename to lesson/lesson15.md diff --git a/lesson16.md b/lesson/lesson16.md similarity index 100% rename from lesson16.md rename to lesson/lesson16.md diff --git a/lesson17.md b/lesson/lesson17.md similarity index 100% rename from lesson17.md rename to lesson/lesson17.md diff --git a/lesson2.md b/lesson/lesson2.md similarity index 92% rename from lesson2.md rename to lesson/lesson2.md index e5f3360..1e9066f 100644 --- a/lesson2.md +++ b/lesson/lesson2.md @@ -5,6 +5,7 @@ - Методология процедурно-ориентированного и объектно-ориентированного программирования - Объекты (cостояние, поведение, уникальность) - Классы. Инкапсуляция. Наследование. Полиморфизм. +- Основы Объектно-Ориентированного Программирования (ООП) - Типы отношений между классами Наследование, агрегация, композиция, ассоциация. - Достоинства/Недостатки ООП. Библиотеки vs фреймворки. - Дополнительно: @@ -30,6 +31,9 @@ - Модификаторы доступа. Область Видимости. ## Домашнее задание + +> Правка к видео: ArrayStorage.delete() - вместо `storage[i] = null` нужно `storage[size-1] = null` + - Прочитать Соглашения по именованию. - Реализовать `ArrayStorage.update` - Сделать проверки: в `update/delete/get` - резюме есть в storage, в `save`- нет в storage: `System.out.println("Resume ...")`. diff --git a/lesson3.md b/lesson/lesson3.md similarity index 87% rename from lesson3.md rename to lesson/lesson3.md index e86bcc0..36b8407 100644 --- a/lesson3.md +++ b/lesson/lesson3.md @@ -8,12 +8,15 @@ - Object. Контракт equals/hashCode - Интерфейсы - Полиморфизм, abstract +- [Java Core. Вопросы к собеседованию](http://info.javarush.ru/translation/2014/02/12/Java-Core-Вопросы-к-собеседованию-ч-1.html) ## Сложность алгоритмов - Алгоритмы и структуры данных для начинающих: сложность алгоритмов - Time complexity - Временная сложность алгоритма - Вычислительная сложность + +## Паттерн проектирования Шаблонный метод - Шаблонный метод ## Домашнее задание diff --git a/lesson4.md b/lesson/lesson4.md similarity index 100% rename from lesson4.md rename to lesson/lesson4.md diff --git a/lesson5.md b/lesson/lesson5.md similarity index 62% rename from lesson5.md rename to lesson/lesson5.md index fdc77b0..169a361 100644 --- a/lesson5.md +++ b/lesson/lesson5.md @@ -8,6 +8,8 @@ - Структуры данных в картинках - Инициализация полей в Java - Java собеседование по коллекциям +- [Часто задаваемые на собеседованиях вопросы по классам коллекциям в Java](http://info.javarush.ru/translation/2013/10/08/Часто-задаваемые-на-собеседованиях-вопросы-по-классам-коллекциям-в-Java-Часть-2-.html#1) +- [Собеседование по Java — коллекции](http://javastudy.ru/interview/collections/) ## Домашнее задание -Выделить общий класс `AbstractStorage` и реализовать подклассы `ListStorage` и `MapStorage`. Выбор реализации List и Map за вами. \ No newline at end of file +Выделить общий класс `AbstractStorage` и реализовать подклассы `ListStorage` и `MapStorage`. Выбор реализации List и Map за вами. diff --git a/lesson6.md b/lesson/lesson6.md similarity index 100% rename from lesson6.md rename to lesson/lesson6.md diff --git a/lesson7.md b/lesson/lesson7.md similarity index 100% rename from lesson7.md rename to lesson/lesson7.md diff --git a/lesson8.md b/lesson/lesson8.md similarity index 100% rename from lesson8.md rename to lesson/lesson8.md diff --git a/lesson9.md b/lesson/lesson9.md similarity index 100% rename from lesson9.md rename to lesson/lesson9.md diff --git a/lesson1.md b/lesson1.md deleted file mode 100644 index 0b1fc5c..0000000 --- a/lesson1.md +++ /dev/null @@ -1,60 +0,0 @@ - -# Первое занятие - -## Разработка ПО. -- Книга: Мифический человеко-месяц -- Методологии разработки ПО -- Ещё раз про семь основных методологий разработки - -## Обзор инструментов и технологий. -- Обзор популярности инструментов и технологий Java за 2014г. -- Дополнительно: - - Автоматизированные сборки в Java - -## Обзор языка Java -- Java, JVM, JIT-компиляция - -![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) - -- Programming languages TIOBE Index -- ME, SE (русский), EE (русский) -- Oracle Java8 Home -- Дополнительно: - - Java version and vendor data analyzed - - Most Popular Java EE Servers - - Что такое Java? История создания - - Понимаем основы Java garbage collection - -## Системы управления версиями. Git. -- Система управления версиями. -- VCS/DVSC. - -![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) - -- Популярность разный VSC -- Книга по Git - -## Настройка окружения -- Idea Wiki (поставить кодировку UTF-8, поменять фонт по умолчанию на DejaVu) -- git занести в переменная окружения PATH, перезапустить cmd -- Создайте локальную копию нашего проекта: `git clone https://github.com/School-IT-Programm/resume-storage.git` -- Перейти в каталог проекта: `cd resume-storage` -- `git remote -v` -- `git remote set-url origin https://github.com/School-IT-Programm/resume-storage.git` - настройка pull -- `git remote set-url --push origin https://github.com/[YouGitHub/YourRepo].git` - настройка push -- `git push -u origin master` - -## Насторойка проекта. Ветка HW1. Debug -- Отладчик IntelliJ IDEA -- Эффективная работа с кодом в IntelliJ IDEA - -## Домашнее задание -- Модифицировать класс `ArrayStorage`: хранить все резюме в начале storage (без дырок null), чтобы не перебирать каждый раз все 10000 элементов. -``` -Хранеие резюме в storage (от 0 до size-1 элементов null нет): - -r1, r2, r3,..., rn, null, null,..., null -<---- size -----> -<---- storage.length ---------------> -``` -- Посмотреть на класс `Arrays`. Там есть полезные вещи, которые могут упростить код `ArrayStorage`. diff --git a/src/MainArray.java b/src/MainArray.java index 20f1f14..b1cb33b 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -3,7 +3,8 @@ import java.io.InputStreamReader; /** - * Test for com.urise.webapp.storage.ArrayStorage + * Interactive test for ArrayStorage implementation + * (just run, no need to understand) */ public class MainArray { private final static ArrayStorage ARRAY_STORAGE = new ArrayStorage(); diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 17ba8c0..b15b81e 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,5 +1,5 @@ /** - * Test for com.urise.webapp.storage.ArrayStorage + * Test for your ArrayStorage implementation */ public class MainTestArrayStorage { static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); diff --git a/src/Resume.java b/src/Resume.java index 937c6a7..8de4e4b 100644 --- a/src/Resume.java +++ b/src/Resume.java @@ -1,5 +1,5 @@ /** - * com.urise.webapp.model.Resume class + * Initial resume class */ public class Resume { From 15f213e7f92ff08da5c13e0c6236130aee820c05 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 25 Jul 2018 16:25:45 +0300 Subject: [PATCH 03/71] Update lesson1.md --- lesson/lesson1.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 3e8a4f3..e0d363b 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -20,7 +20,9 @@ - [Bash — шпаргалка для начинающих](https://tproger.ru/translations/bash-cheatsheet) - [Интерактивный курс по SQL](http://www.sql-ex.ru/) - [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) -- **Обновление!!**[Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) +- **Обновление!!* + - [The State of Java in 2018](http://www.baeldung.com/java-in-2018) + - [Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) - [Java Tools and Technologies Landscape Report 2016](https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/) - [Java Tools and Technologies Landscape for 2014](http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014) - **Дополнительно:** From b13a34aa2a76527be78bb6859af6b7221577ad48 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 21 Aug 2018 17:39:29 +0300 Subject: [PATCH 04/71] Update lesson1.md --- lesson/lesson1.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index e0d363b..bacd7de 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -1,7 +1,6 @@ # Первое занятие ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар-презентация обучения на проекте BaseJava](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) -#### [Итоговый пример приложения, разрабатываемого в рамках данного курса (на примере резюме Григория Кислина)](https://javawebinar.github.io/) ### Подготовка рабочего окружения - Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) @@ -116,3 +115,6 @@ r1, r2, r3,..., rn, null, null,..., null 6. `Resume r` — давай переменным осмысленные имена, например `resume`. `r` допустимо в коротких циклах и лямбдах. 7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового 8. По заданию необходимо посмотреть в классе `Arrays методы`, которые помогут упростить реализацию ваших методов `clear()` и `getAll()` + +## Дополнительно (подход к обучению, мышлению, решению проблем): +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар "Быть программистом: от детства к зрелости"](http://javaops.ru/view/resources/tobe-programmer) From 20b69535cae670de0602a83f226765e4f74a5928 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 21 Aug 2018 17:40:22 +0300 Subject: [PATCH 05/71] Update lesson1.md --- lesson/lesson1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index bacd7de..b776d01 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -116,5 +116,5 @@ r1, r2, r3,..., rn, null, null,..., null 7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового 8. По заданию необходимо посмотреть в классе `Arrays методы`, которые помогут упростить реализацию ваших методов `clear()` и `getAll()` -## Дополнительно (подход к обучению, мышлению, решению проблем): -### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар "Быть программистом: от детства к зрелости"](http://javaops.ru/view/resources/tobe-programmer) +# Дополнительно (подход к обучению, мышлению, решению проблем): +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Вебинар "Быть программистом: от детства к зрелости"](http://javaops.ru/view/resources/tobe-programmer) From cf19608bc76ba5e0f9d66415d9504d4855708696 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 21 Aug 2018 17:45:18 +0300 Subject: [PATCH 06/71] Update lesson1.md --- lesson/lesson1.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index b776d01..9684d98 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -116,5 +116,7 @@ r1, r2, r3,..., rn, null, null,..., null 7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового 8. По заданию необходимо посмотреть в классе `Arrays методы`, которые помогут упростить реализацию ваших методов `clear()` и `getAll()` -# Дополнительно (подход к обучению, мышлению, решению проблем): -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Вебинар "Быть программистом: от детства к зрелости"](http://javaops.ru/view/resources/tobe-programmer) +# Дополнительно (подход к обучению, мышлению, решению проблем) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Вебинар "Быть программистом: от детства к зрелости"](https://www.youtube.com/watch?v=D5Hej0TyLaU) + - [Слайды вебинара](https://docs.google.com/presentation/d/1YwtCCZsaGMdl-V15kTDHiJxiS52IAl-qqheNPpiNr54/) + From 4503f4d5677727972fbc8f994ffd26ce9dde83f1 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 22 Aug 2018 01:00:52 +0300 Subject: [PATCH 07/71] Update lesson1.md --- lesson/lesson1.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 9684d98..e87a955 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -116,7 +116,12 @@ r1, r2, r3,..., rn, null, null,..., null 7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового 8. По заданию необходимо посмотреть в классе `Arrays методы`, которые помогут упростить реализацию ваших методов `clear()` и `getAll()` -# Дополнительно (подход к обучению, мышлению, решению проблем) +# Дополнительно (как учиться программированию) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Вебинар "Быть программистом: от детства к зрелости"](https://www.youtube.com/watch?v=D5Hej0TyLaU) - [Слайды вебинара](https://docs.google.com/presentation/d/1YwtCCZsaGMdl-V15kTDHiJxiS52IAl-qqheNPpiNr54/) - +## Советы по обучению + - Учись грамотно формулировать проблему. Проблема "у меня не работает" может иметь тысячи причин. В процессе формулирования очень часто приходит ее решение. + - Учись инвестигировать проблему. Внимательное чтение логов и умение дебажить - основные навыки разработчика. В логах надо читать верх самого нижнего эксепшена - там причина всей портянки. + - Грамотно уделяй время каждой проблеме. Две крайности - сразу бросаться за помощью и бится нам ней часами. Пробуй решить ее сам и в зависимости от проблемы выделяй на это разумное время. + - Получай в процессе решения обратную связь - в том ли направлении ты идешь. + - [Советы новичкам](http://blog.csssr.ru/2016/09/19/how-to-be-a-beginner-developer) From cea1e9404ab1d9a983d53df167d7128875840c06 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 5 Sep 2018 11:00:42 +0300 Subject: [PATCH 08/71] Update lesson1.md --- lesson/lesson1.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index e87a955..5e0fbb8 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -1,6 +1,6 @@ # Первое занятие -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар-презентация обучения на проекте BaseJava](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Видеообзор проекта Basejava](https://www.youtube.com/watch?v=0ydTRfKS9yY) ### Подготовка рабочего окружения - Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) @@ -87,7 +87,6 @@ r1, r2, r3,..., rn, null, null,..., null <----- size -----> <------- storage.length (10000) -------> ``` -- Посмотрите на класс `java.util.Arrays`. В нем есть полезные методы, которые помогут вам написать более простой и понятный код - Протестируйте вашу реализацию с помощью классов `MainArray.main()` и `MainTestArrayStorage.main()` - Изучите дополнительные материалы по IntelliJ IDEA: - [Idea Wiki](https://github.com/JavaOPs/topjava/wiki/IDEA) ([поставьте кодировку UTF-8](https://github.com/JavaOPs/topjava/wiki/IDEA#Поставить-кодировку-utf-8), [поменяйте шрифт по умолчанию на DejaVu](https://github.com/JavaOPs/topjava/wiki/IDEA#Поменять-фонт-по-умолчанию-dejavu)) @@ -114,7 +113,6 @@ r1, r2, r3,..., rn, null, null,..., null 5. Не игнорируй подсказки IDEA (подсвечивает) 6. `Resume r` — давай переменным осмысленные имена, например `resume`. `r` допустимо в коротких циклах и лямбдах. 7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового -8. По заданию необходимо посмотреть в классе `Arrays методы`, которые помогут упростить реализацию ваших методов `clear()` и `getAll()` # Дополнительно (как учиться программированию) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Вебинар "Быть программистом: от детства к зрелости"](https://www.youtube.com/watch?v=D5Hej0TyLaU) From b6fe98c43257f09c35e6216efa9cffd45cd6cce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Tue, 23 Oct 2018 18:26:43 +0300 Subject: [PATCH 09/71] Update lesson1.md --- lesson/lesson1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 5e0fbb8..f340f2e 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -29,6 +29,8 @@ ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) - [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) (wiki) +- [Что такое JDK? Введение в средства разработки Java](https://topjava.ru/blog/what-is-the-jdk) +- [Что такое JRE? Введение в среду выполнения Java](https://topjava.ru/blog/what-is-the-jre) - [Что такое Java? История создания](http://www.intuit.ru/studies/courses/16/16/lecture/27105) - [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) From 49855f6d72b9c97856f61d4c1c8aefc29d1d9eb7 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 20 Nov 2018 22:01:00 +0300 Subject: [PATCH 10/71] Update lesson1.md --- lesson/lesson1.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index f340f2e..2b5e449 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -17,15 +17,13 @@ ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) - [Bash — шпаргалка для начинающих](https://tproger.ru/translations/bash-cheatsheet) -- [Интерактивный курс по SQL](http://www.sql-ex.ru/) -- [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) - **Обновление!!* - [The State of Java in 2018](http://www.baeldung.com/java-in-2018) - [Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) - [Java Tools and Technologies Landscape Report 2016](https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/) - [Java Tools and Technologies Landscape for 2014](http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014) - **Дополнительно:** - - [Автоматизированная сборка проекта в Java](http://spring-projects.ru/guides/maven/) + - [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) - [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) (wiki) From b67a4a098c56a978cc0e0a60f9e4b8093bc3a830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Thu, 17 Jan 2019 21:40:09 +0300 Subject: [PATCH 11/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e288257..6f275f7 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ # Изучайте [первое открытое занятие](lesson/lesson1.md). ### Внизу урока есть первое домашнее задание, по которому можно оценить свой уровень готовности к проекту. -## Программа +## Программа ### [Регистрация](http://javaops.ru/reg/basejava) ### Открытое занятие 1 - [Презентация проекта](lesson/lesson1.md#-Вебинар-ПРЕЗЕНТАЦИЯ-обучения) From 775207c0379665959ce5f1042a136ab007e6894a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Thu, 17 Jan 2019 21:56:17 +0300 Subject: [PATCH 12/71] Update README.md --- README.md | 180 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 134 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 6f275f7..197623f 100644 --- a/README.md +++ b/README.md @@ -27,84 +27,172 @@ ## Программа ### [Регистрация](http://javaops.ru/reg/basejava) ### Открытое занятие 1 - - [Презентация проекта](lesson/lesson1.md#-Вебинар-ПРЕЗЕНТАЦИЯ-обучения) - - [Разработка ПО](lesson/lesson1.md#-1-Разработка-ПО) - - [Обзор языка Java](lesson/lesson1.md#-3-Обзор-языка-java) - - [Системы управления версиями. Git](lesson/lesson1.md#-4-Системы-управления-версиями-git) - - [ПЕРВОЕ ДОМАШНЕЕ ЗАДАНИЕ](lesson/lesson1.md#Домашнее-задание-hw1) + - Обзор курса и методики обучения + - Подготовка и настройка рабочего окружения + - Подходы, применяемые при разработке ПО + - Обзор инструментов и технологий, используемых Java-разработчиками + - Введение в язык Java: история создания, JVM, JIT-компиляция + - Системы управления версиями. Git + - Домашнее задание ### Занятие 2 - - [Принципы ООП](lesson/lesson2.md#Принципы-ООП) - - [Структура памяти: куча, стек, регистры, константы](lesson/lesson2.md#Структура-памяти-куча-стек-регистры-константы) - - [Типы данных. Пакеты](lesson/lesson2.md#Типы-данных-Пакеты) + - Введение в объектно-ориентированное программирование + - Принципы ООП + - Модификаторы доступа + - Классы-обертки + - Классы и объекты + - Структура памяти java-программы: Heap (куча), Stack (стек) + - Типы данных + - Пакетная организация файлов + - Домашнее задание ### Занятие 3 - - [Объектная модель в Java](lesson/lesson3.md#Объектная-модель-в-java) - - [Сложность алгоритмов](lesson/lesson3.md#Сложность-алгоритмов) - - [Паттерн проектирования Шаблонный метод](https://github.com/JavaOPs/JavaSE-Web/blob/master/lesson/lesson3.md#Паттерн-проектирования-Шаблонный-метод) + - Разбор домашнего задания + - Обзор суперкласса Object + - Связь между equals() и hashCode() + - Статические методы и переменные + - Программирование с помощью интерфейсов + - Абстрактные классы + - Сложность алгоритмов + - Паттерн проектирования Шаблонный метод + - Домашнее задание ### Занятие 4 - - [Работа со строками](lesson/lesson4.md#Работа-со-строками) - - [Исключения](lesson/lesson4.md#Исключения) - - [Reflection. Аннотации. Модульное тестирование](lesson/lesson4.md#reflection-Аннотации-Модульное-тестирование) + - Разбор домашнего задания + - Работа со строками: String, StringBuilder, StringBuffer + - String literal pool + - Исключения (Exceptions) + - Конструктор + - Ключевые слова: this, super + - Reflection + - Аннотации в Java 8 + - Введение в модульное тестирование. JUnit + - Домашнее задание ### Занятие 5 - - [Контейнеры/коллекции](lesson/lesson5.md#Контейнерыколлекции) + - Разбор домашнего задания + - Иерархия классов Коллекций + - Списки (List) + - Множества (Set) + - Ассоциативные массивы (Map) + - Введение в Iterator + - Тестирование коллекций + - Домашнее задание ### Занятие 6 - - [Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы](lesson/lesson6.md#iterator--iterable-Вложенные-внутренние-локальные-и-анонимные-классы) - - [Новое в Java 8](lesson/lesson6.md#Новое-в-java-8) + - Разбор домашнего задания + - Autoboxing and Unboxing + - Паттерн проектирования Итератор + - Вложенные классы + - Внутренние классы + - Локальные классы + - Анонимные классы + - Введение в лямбды + - Функциональный интерфейс + - Домашнее задание ### Занятие 7 - - [Параметризация. Стирание типов](lesson/lesson7.md#Параметризация-Стирание-типов) - - [Логирование](lesson/lesson7.md#Логирование) - - [Синглетон, Enum](lesson/lesson7.md#Синглетон-enum) + - Разбор домашнего задания + - Дженерики (Generic) + - Введение в логирование. Log4J + - Стандартный логер - Java Logging API + - Паттерн проектирования - Синглтон + - Перечисляемые типы (Enum) + - Объектная модель + - Домашнее задание ### Занятие 8 - - [Работа с датами и временем](lesson/lesson8.md#Работа-с-датами-и-временем) - - [Работа с файлами и ресурсами](lesson/lesson8.md#Работа-с-файлами-и-ресурсами) + - Разбор домашнего задания + - Классы работы с датами: Date, Calendar, TimeZone + - Дата и время в Java 8 + - Внешние библиотеки: Joda Time library + - Работа с файловой системой: класс File + - try-with-resources + - Домашнее задание ### Занятие 9 - - [Ввод/вывод](lesson/lesson9.md#Вводвывод) - - [Сериализация](lesson/lesson9.md#Сериализация) - - [NIO](lesson/lesson9.md#nio) - - [Основы Java 8 Stream API](lesson/lesson9.md#Основы-java-8-stream-api) + - Разбор домашнего задания + - Обзор пакета java.io + - Классы чтения/записи потоков: InputStream/OutputStream + - Паттерн проектирования Декоратор + - Работа с классами чтения/записи символов: Reader и Writer + - Сериализация + - Обзор пакета java.nio + - Введение в Java 8 Stream API + - Домашнее задание ### Занятие 10 - - [Формат XML. Работа с XML в Java](lesson/lesson10.md#Формат-xml-Работа-с-xml-в-java) - - [JSON](lesson/lesson10.md#json) - - [DataInputStream / DataOutputStream](lesson/lesson10.md#datainputstream--dataoutputstream) + - Разбор домашнего задания + - Паттерн проектирования Стратегия + - Работа с XML + - Работа с JSON: Google GSON и Jackson + - Введение в REST + - DataInputStream/DataOutputStream + - Домашнее задание ### Занятие 11 - - [Многопоточность. Параллельное выполнение.](lesson/lesson11.md#Многопоточность-Параллельное-выполнение) - - [Потоки. Синхронизация](lesson/lesson11.md#Потоки-Синхронизация) - - [Ленивая инициализация, JMM](lesson/lesson11.md#Ленивая-инициализация-jmm) + - Процессы и потоки + - Синхронизация методов и блоков + - Закон Мура + - Закон Амдала + - Обзор методов класса Object + - Ленивая инициализация + - Java Memory Model + - Взаимная блокировка + - Домашнее задание ### Занятие 12 - - [java.util.concurrent](lesson/lesson12.md#javautilconcurrent) + - Разбор домашнего задания + - Обзор java.util.concurrent + - Синхронизаторы + - ThreadLocal переменные + - Сравнение с обменом (Compare-and-swap) + - Домашнее задание ### Занятие 13 - - [Базы данных. Реляционные СУБД. PostgreSQL](lesson/lesson13.md#Базы-данных-Реляционные-СУБД-postgresql) - - [Конфигурирование данных в Java проекте](lesson/lesson13.md#Конфигурирование-данных-в-java-проекте) - - [Подключение DB в проект](lesson/lesson13.md#Подключение-db-в-проект) + - Разбор домашнего задания + - Введение в реляционные базы данных + - Язык SQL + - Обзор NoSQL баз данных + - Установка и настройка СУБД PostgreSQL + - Работа с базами данных из IDEA + - Конфигурирование базы данных и каталога хранения + - Подключение базы данных к проекту + - Обзор JDBC-архитектуры + - Домашнее задание ### Занятие 14 - - [JOIN](lesson/lesson14.md#join) - - [Транзакции](lesson/lesson14.md#Транзакции) - - [Установка/запуск Tomcat](lesson/lesson14.md#Установказапуск-tomcat) + - Разбор домашнего задания + - Операции соединения таблиц. JOIN + - Транзакции + - Требования к транзакциям. ACID + - Уровни изоляции транзакций в SQL + - Установка и настройка контейнера сервлетов Tomcat + - Домашнее задание ### Занятие 15 - - [HTML, Tomcat](lesson/lesson15.md#html-tomcat) - - [Сервлеты](lesson/lesson15.md#Сервлеты) + - Разбор домашнего задания + - Введение в HTML + - Основы протокола HTTP + - Настройка web.xml + - Развертывание (деплой) web-приложения в Tomcat + - Сервлеты + - Домашнее задание ### Занятие 16 - - [JSP](lesson/lesson16.md#jsp) - - [JSTL](lesson/lesson16.md#jstl) + - Разбор домашнего задания + - Жизненный цикл сервлета + - Создание динамических страниц. JSP + - Расширенные возможности JSP: JSTL + - Redirect и Forward + - CRUD + - Домашнее задание ### Занятие 17 - - [Деплой в Heroku](lesson/lesson17.md#Деплой-в-heroku) - - [Classloader](lesson/lesson17.md#classloader) - - [Обзор Java Enterprise](lesson/lesson17.md#Обзор-java-enterprise) + - Разбор домашнего задания + - Деплой приложения в облачный сервис Heroku + - Загрузка классов в Java. Classloader + - Домашнее задание ## Рекомендуемые книги - YAKOV FAIN: Программирование на Java для начинающих From 75e6adcf4a9d346a8c98165a7c16f5e82a02fee6 Mon Sep 17 00:00:00 2001 From: ichimax Date: Thu, 17 Jan 2019 22:08:54 +0300 Subject: [PATCH 13/71] rm old lessons --- lesson/lesson10.md | 19 ------------------- lesson/lesson11.md | 31 ------------------------------- lesson/lesson12.md | 35 ----------------------------------- lesson/lesson13.md | 29 ----------------------------- lesson/lesson14.md | 26 -------------------------- lesson/lesson15.md | 26 -------------------------- lesson/lesson16.md | 21 --------------------- lesson/lesson17.md | 24 ------------------------ lesson/lesson2.md | 41 ----------------------------------------- lesson/lesson3.md | 24 ------------------------ lesson/lesson4.md | 28 ---------------------------- lesson/lesson5.md | 15 --------------- lesson/lesson6.md | 20 -------------------- lesson/lesson7.md | 46 ---------------------------------------------- lesson/lesson8.md | 21 --------------------- lesson/lesson9.md | 25 ------------------------- 16 files changed, 431 deletions(-) delete mode 100644 lesson/lesson10.md delete mode 100644 lesson/lesson11.md delete mode 100644 lesson/lesson12.md delete mode 100644 lesson/lesson13.md delete mode 100644 lesson/lesson14.md delete mode 100644 lesson/lesson15.md delete mode 100644 lesson/lesson16.md delete mode 100644 lesson/lesson17.md delete mode 100644 lesson/lesson2.md delete mode 100644 lesson/lesson3.md delete mode 100644 lesson/lesson4.md delete mode 100644 lesson/lesson5.md delete mode 100644 lesson/lesson6.md delete mode 100644 lesson/lesson7.md delete mode 100644 lesson/lesson8.md delete mode 100644 lesson/lesson9.md diff --git a/lesson/lesson10.md b/lesson/lesson10.md deleted file mode 100644 index 1c279e7..0000000 --- a/lesson/lesson10.md +++ /dev/null @@ -1,19 +0,0 @@ - -# Десятое занятие - -## Разбор Домашнего Задания-9: - -## Формат XML. Работа с XML в Java -- XML формат и технологии -- Wiki: XML, XSL , DOM, SAX, StAX, JAXB -- Работа с XML в Java. Реализация хранения в XML. - -## JSON -- JSON. JSON в JavaScript. REST -- Работа с JSON в Java: Google GSON и Jackson. Реализация хранения в JSON. - -## DataInputStream / DataOutputStream -- Реализация Store на основе `DataInputStream/DataOutputStream`. - -## Домашнее задание -- Сделать и протестировать реализацию `DataStreamSerializer` \ No newline at end of file diff --git a/lesson/lesson11.md b/lesson/lesson11.md deleted file mode 100644 index 1a1e7a9..0000000 --- a/lesson/lesson11.md +++ /dev/null @@ -1,31 +0,0 @@ - -# Одиннадцатое занятие - -## Многопоточность. Параллельное выполнение. -![Закон Мура](https://www.karlrupp.net/wp-content/uploads/2015/06/40-years-processor-trend.png) -- Закон Мура -- Закон Амдала - -![Concurrent vs Parallel](https://joearms.github.io/images/con_and_par.jpg) - -## Потоки. Синхронизация -- Потоки выполнения. Синхронизация. -- Методы wait(), notify(), notifyAll() класса Object - -## Ленивая инициализация, JMM -- Параллелизм в Java -- Реализация Singleton в JAVA -- Double checked locking -- Java Memory Model. final, volatile -- Initialization-on-demand holder idiom - -### Ресурсы -- Алексей Владыкин, Основы многопоточность в Java -- Виталий Чибриков, Java. Многопоточность -- Computer Science Center, курс Параллельное программирование -- Юрий Ткач, курс Advanced Java - Concurrency -- Головач, курс Java Multithreading - -## Домашнее задание -- Реализовать deadlock -- Взаимная блокировка diff --git a/lesson/lesson12.md b/lesson/lesson12.md deleted file mode 100644 index 47156cd..0000000 --- a/lesson/lesson12.md +++ /dev/null @@ -1,35 +0,0 @@ - -# Двенадцатое занятие - -## Разбор Домашнего Задания-11: реализация dead lock. - -## java.util.concurrent -- Обзор java.util.concurrent.* -- Compare-and-swap -- Справочник по синхронизаторам java.util.concurrent.* -- Использование ThreadLocal переменных - -> Замечания по видео: - - ThreadLocal DATE_FORMAT = new ThreadLocal() { - @Override - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); - }; - }; - -можно написать через лямбду: - - ThreadLocal.withInitial(() -> new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")); - -А лучше использовать потокобезопасный `DateTimeFormatter` Java 8 Time API: - - DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); - -## Разбор домашнего задания 10го урока - -## Домашнее задание: -- Установить PostgreSQL -- Посомтреть на реляционные базы данных и SQL: - - Введение в базы данных - - Основы SQL diff --git a/lesson/lesson13.md b/lesson/lesson13.md deleted file mode 100644 index 2ad74ff..0000000 --- a/lesson/lesson13.md +++ /dev/null @@ -1,29 +0,0 @@ - -# Тринадцатое занятие - -### Базы данных. Реляционные СУБД. PostgreSQL -- DB-Engines Ranking -- Реляционная СУБД -- Введение в базы данных -- Реляционные базы vs NoSQL. SQL. Денормализация. PK, FK, Cascade -- PostgreSQL. Надёжность -- Создание базы резюме. Работа с базами данных из IDEA -- IDEA Database tools. - -### Конфигурирование данных в Java проекте -- Properties sample -- Конфигурирование DB и каталога хранения - -### Подключение DB в проект -- JDBC. JDBC Architecture. -- ConnectionFactory. Реализация SqlStorage. -- Ресурсы: - - Книга: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL - - Работа с базами данных с помощью JDBC драйвера - - Уроки по JDBC - -### ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW13 -- Доделать `SqlStorage` без контактов и секций. - - Для работы с DB надо в lib и проект добавить драйвер базы данных - - Запустить `SqlStorageTest` (в `AbstractStorageTest` контакты и секции закоменченны), креденшелы к базе взять из `Config` -- Вынести общий код (`getConnection(), prepareStatement, catch SQLException`) в класс `SqlHelper`. diff --git a/lesson/lesson14.md b/lesson/lesson14.md deleted file mode 100644 index f625d1d..0000000 --- a/lesson/lesson14.md +++ /dev/null @@ -1,26 +0,0 @@ - -# Четырнадцатое занятие - -### Разбор HW13 - -### JOIN -- LEFT, RIGHT, INNER JOIN -- Добавляем в `SqlStorage` контакты - -### Транзакции. -- Транзакция. ACID. Уровни изоляции транзакций. -- Уровни изоляции транзакций в SQL -- Добавляем в `SqlStorage` транзакции -- Batch execute. - -### Установка/запуск Tomcat -- Скачать и установить Tomcat 8. Устанавливать лучше простым копированием из архива в каталог (в том числе и для unix). Следите чтобы в пути не было пробелов и национальных букв. -- Для доступа к Tomсat Manager добавьте в конфигурацию Tomcat `TOMCAT_HOME\conf\tomcat-users.xml` права: -``` - -``` -- Запуск из `TOMCAT_HOME\bin\`: `catalina.bat start` - -## Домашнее задание HW14 -- Закончить реализацию `SqlStorage` с контактами -- Добавить `TextSection` в базу данных (`init_db.sql`) и `SqlStorage`. diff --git a/lesson/lesson15.md b/lesson/lesson15.md deleted file mode 100644 index 4939684..0000000 --- a/lesson/lesson15.md +++ /dev/null @@ -1,26 +0,0 @@ -# Пятнадцатое занятие - -### Разбор HW14 - -### HTML, Tomcat -- Протокол HTTP. Смотрим демо приложение в Chrome -> Инструменты разработчика -- Добавление в проект Web Facet. web.xml. Постороение/cтруктура WAR. Статические ресурсы. -- Настройка и деплой в Tomcat. Tomcat manager. -- Запуск Tomcat из IDEA. Динамическое обновление без передеплоя. - -### Сервлеты -- Создаем Servlet. Параметры. Кодировка. -- Дополнительно: - - How do servlets work? - - Язык программирования Java и среда NetBeans: Введение в сетевое программирование - - Основы работы с HTML - - Учебник HTML - - Технологии Java для разработки веб-приложений - - Таблицы стилей CSS - - Основы JavaScript - -## Домашнее задание HW15 -- Сделать реализацию `SqlStorage.getAll` через 2 отдельных запроса: отдельно резюме и отдельно контакты. -- Добавить в реализацию `SqlStorage` и в базу секции (кроме `OrganizationSection`). Для `ListSection` склеиваем строки через `\n`. -- Сделать отображение таблицы резюме в сервлете. - - HTML таблицы diff --git a/lesson/lesson16.md b/lesson/lesson16.md deleted file mode 100644 index 6e431f3..0000000 --- a/lesson/lesson16.md +++ /dev/null @@ -1,21 +0,0 @@ -# Шестнадцатое занятие - -### Разбор HW15 -- Почему вы никогда не должны использовать MongoDB -- Жизненный цикл сервлета -- Tomcat maxThreads configuration - -### JSP -- Что такое JSP. Wiki JSP -- Predefined Variables in JSP -- Стандартные элементы action -- How to use relative paths in JSP -- Отличие Redirect от Forward - -### JSTL -- JSTL -- JSTL для написания JSP страниц - -## Домашнее задание HW15 -- Доделать логику сервлета -- Дополнить отображение и редактирование JSP секциями diff --git a/lesson/lesson17.md b/lesson/lesson17.md deleted file mode 100644 index e2cbc7c..0000000 --- a/lesson/lesson17.md +++ /dev/null @@ -1,24 +0,0 @@ -# Семнадцатое занятие - -### Разбор HW16 - -### Деплой в Heroku -- Deployment with the Heroku CLI - -### Classloader -- Загрузка классов в Java -- Apache Tomcat Class Loader - -## Обзор Java Enterprise -- Из юниоров в разработчики: получаем первую работу -- Java Tools and Technologies Landscape for 2014 -- Java Tools and Technologies Landscape Report 2016 - -#### Spring Pet-Clinic -- Spring PetClinic Sample Application -- Demo -- Presentation - -#### Java Enterprise project Topjava -- Java Enterprise: Вводное занятие -- Demo приложение diff --git a/lesson/lesson2.md b/lesson/lesson2.md deleted file mode 100644 index 1e9066f..0000000 --- a/lesson/lesson2.md +++ /dev/null @@ -1,41 +0,0 @@ - -# Второе занятие - -## Принципы ООП. -- Методология процедурно-ориентированного и объектно-ориентированного программирования -- Объекты (cостояние, поведение, уникальность) -- Классы. Инкапсуляция. Наследование. Полиморфизм. -- Основы Объектно-Ориентированного Программирования (ООП) -- Типы отношений между классами Наследование, агрегация, композиция, ассоциация. -- Достоинства/Недостатки ООП. Библиотеки vs фреймворки. -- Дополнительно: - - Что такое ООП и с чем его едят? - - Объектно ориентированное программирование - - Николай Алименков — Парадигмы ООП - - Концепции объектно-ориентированного программирования - -### Структура памяти: куча, стек, регистры, константы - - JVM изнутри - оптимизация и профилирование. - - Stack and Heap - - Дополнительно: - - Из каких частей состоит память java процесса. - - Permanent область памяти - - Java thread stack - - Размер Java объектов - -### Типы данных. Пакеты. - - Типы данных - - Классы- оберки - - Ссылочные типы - - Пакеты - - Модификаторы доступа. Область Видимости. - -## Домашнее задание - -> Правка к видео: ArrayStorage.delete() - вместо `storage[i] = null` нужно `storage[size-1] = null` - -- Прочитать Соглашения по именованию. -- Реализовать `ArrayStorage.update` -- Сделать проверки: в `update/delete/get` - резюме есть в storage, в `save`- нет в storage: `System.out.println("Resume ...")`. -- Сделать в save проверку на переполнениеe: `System.out.println("...")`. -- Избавится от дублирования в коде `ArrayStorage` diff --git a/lesson/lesson3.md b/lesson/lesson3.md deleted file mode 100644 index 36b8407..0000000 --- a/lesson/lesson3.md +++ /dev/null @@ -1,24 +0,0 @@ - -# Третье занятие - -## Разбор Домашнего Задания-2 - -## Объектная модель в Java -- static -- Object. Контракт equals/hashCode -- Интерфейсы -- Полиморфизм, abstract -- [Java Core. Вопросы к собеседованию](http://info.javarush.ru/translation/2014/02/12/Java-Core-Вопросы-к-собеседованию-ч-1.html) - -## Сложность алгоритмов -- Алгоритмы и структуры данных для начинающих: сложность алгоритмов -- Time complexity -- Временная сложность алгоритма -- Вычислительная сложность - -## Паттерн проектирования Шаблонный метод -- Шаблонный метод - -## Домашнее задание -- Закончить реализацию `AbstractArrayStorage`, `ArrayStorage`, `SortedArrayStorage` (`SortedArrayStorage` хранит элементы отсортированными, сортировать весь массив не надо). -- Сделать проверку `ArrayStorage.update` diff --git a/lesson/lesson4.md b/lesson/lesson4.md deleted file mode 100644 index 4207304..0000000 --- a/lesson/lesson4.md +++ /dev/null @@ -1,28 +0,0 @@ - -# Четвертое занятие - -## Разбор Домашнего Задания-3 - -## Работа со строками. -- Строки в Java. Кодировка. -- Управление строками, функции для работы со строками в Java. -- StringBuilder vs StringBuffer -- String literal pool - -## Исключения - - Исключения (Exceptions). - - "Java. Эффективное программирование" Джошуа Блох: Исключения. - - Конструктор. this, super - -![image](https://cloud.githubusercontent.com/assets/18701152/15581283/4c2f5348-2374-11e6-8fd2-e4de02d2c389.png) - -## Reflection. Аннотации. Модульное тестирование - - Аннотации - - Введение в Java Reflection API - - Модульное тестирование JUnit 4 - - Тестирование с помощью JUnit (Test Case) - - -## Домашнее задание -Реализовать `AbstractStorageTest` и тесты `ArrayStorageTest` и `SortedArrayStorageTest`. -В `MainReflection` сделать вызов метода `toString` через отражение. diff --git a/lesson/lesson5.md b/lesson/lesson5.md deleted file mode 100644 index 169a361..0000000 --- a/lesson/lesson5.md +++ /dev/null @@ -1,15 +0,0 @@ - -# Пятое занятие - -## Разбор Домашнего Задания-4 - -## Контейнеры/коллекции. -- List, Set, Map, Queue, Iterator, ListIterator -- Структуры данных в картинках -- Инициализация полей в Java -- Java собеседование по коллекциям -- [Часто задаваемые на собеседованиях вопросы по классам коллекциям в Java](http://info.javarush.ru/translation/2013/10/08/Часто-задаваемые-на-собеседованиях-вопросы-по-классам-коллекциям-в-Java-Часть-2-.html#1) -- [Собеседование по Java — коллекции](http://javastudy.ru/interview/collections/) - -## Домашнее задание -Выделить общий класс `AbstractStorage` и реализовать подклассы `ListStorage` и `MapStorage`. Выбор реализации List и Map за вами. diff --git a/lesson/lesson6.md b/lesson/lesson6.md deleted file mode 100644 index 3295fbb..0000000 --- a/lesson/lesson6.md +++ /dev/null @@ -1,20 +0,0 @@ - -# Шестое занятие - -## Разбор Домашнего Задания-5 -- Преобразования Integer и int - -## Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы. -- Iterator / Iterable. -- Вложенные и внутренние классы. Примеры в Collections API: Arrays.asList, ArrayList.iterator -- Локальные и анонимные классы. Comparator - -## Новое в Java 8. -- Lambda выражения. Default методы для Interface. -- Встроенные функциональные интерфейсы. - -## Домашнее задание -- Сделать рефакторинг тестов: `saveOverflow` должно быть только для Array реализаций. -- Рефакторинг: в конструктор Resume добавить второй параметр `fullName` -- Сделать рефакторинг всех реализаций `Storage`: заменить метод `Resume[] getAll()` на `List getAllSorted()` -- Реализовать до конца `MapUuidStorage`. Подумать что еще может быть search key в реализации на основе Map. diff --git a/lesson/lesson7.md b/lesson/lesson7.md deleted file mode 100644 index 30494c9..0000000 --- a/lesson/lesson7.md +++ /dev/null @@ -1,46 +0,0 @@ - -# Седьмое занятие - -## [Разбор Домашнего Задания-6](lesson6.md#Домашнее-задание) - -## Параметризация. Стирание типов. -- Дженерики (Java, обучающая статья) -- Обобщения (Generic) -- Ограничения. - -## Логирование -- Log4J (Apache logging) -- Java Logging API - Tutorial -- Логирование в Java / quick start -- Ведение лога приложения -- Java Logging: история кошмара - -## Синглетон, Enum -- Одиночка (шаблон проектирования) -- Перечисляемые типы (enum) в Java - -## Домашнее задание: -Доменный объект - -Cделать объектную модель резюме (диаграмма и классы). Образец резюме (делаем упрощенно) - - Делать только классы, включаемые в Resume. Resume - главный класс. В него все включается (композиция - строгий вид агрегации). - - Схожие по структуре и функциональности сущности делаем одним классом. - - Модель упрощаем для хранения только необходимой информации для вывода/ редактирования резюме. - - В модели резюме должны быть представлены контакты и следующие разделы: - - PERSONAL("Личные качества") - - OBJECTIVE("Позиция") - - ACHIEVEMENT("Достижения") - - QUALIFICATIONS("Квалификация") - - EXPERIENCE("Опыт работы") - - EDUCATION("Образование") - - В секциях Достижения и Квалификация хранить список строк - - Учесть в классах модели, что обработка резюме (вывод в html, сохранение, чтение) будет сделано следующим образом: -обработка `fullName`, цикл обработки по контактам, цикл обработки по секциям (для секций использовать полиморфизм, как для фигур: круг, квадрат..). -При добавлении/удалении новых видов контактов (например домашний телефон) или разделов изменения в коде (и БД) должны быть минимальны. - -#### Инструменты для рисования: - -- Generate class diagram in IntelliJ IDEA (Help: working with Diagrams) -- Нарисовать и сфотографировать -- Online: www.draw.io -- yEd - Graph Editor diff --git a/lesson/lesson8.md b/lesson/lesson8.md deleted file mode 100644 index d7336ad..0000000 --- a/lesson/lesson8.md +++ /dev/null @@ -1,21 +0,0 @@ - -# Восьмое занятие - -## Разбор Домашнего Задания-7: объектная модель резюме - -## Работа с датами и временем -- Класс Date, Calendar, TimeZone -- Java – Convert date and time between timezone -- Joda Time library -- Java 8 Date API - -## Работа с файлами и ресурсами. - - File. Работа с файловой системой. - - Работа с ресурсами. Правильно освобождаем ресурсы в Java - - Java 7 try-with-resources - -## Домашнее задание -- Переделать модель резюме: учесть, что на одной работе (в одном учебном заведении) можно работать/ учиться в разные периоды и при этом имя организации не дублируется -- Сделать рекурсивный обход и вывод имени файлов в каталогах и подкаталогах (корневой каталог- ваш проект) -- Заполнить в `AbstractStorageTest` резюме данными -- Реализовать `AbstractFileStorage`, базовый класс для хранения резюме в файлах. diff --git a/lesson/lesson9.md b/lesson/lesson9.md deleted file mode 100644 index de787f6..0000000 --- a/lesson/lesson9.md +++ /dev/null @@ -1,25 +0,0 @@ - -# Девятое занятие - -## Разбор Домашнего Задания-8: - -## Ввод/вывод -- Пакет java.io -- Паттерн Декоратор. -- Классы Reader и Writer. - -## Сериализация -- Сериализация объектов (serialization) -- Реализация Storage используя сериализацию. - -## NIO -- NIO Java 7 -- Чтения строк из файла - -## Основы Java 8 Stream API -- Потоки - -## Домашнее задание -- Сделать рекурсивный вывод каталогов с отступом -- Реализовать Storage через java.nio.file.Path. -- Сделать возможным выбор меджу FileStorage и PathStorage для сериализации через ObjectStream. From da6578c3cd85c4b7c2c93adc40060cb44f4b19aa Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 7 Feb 2019 17:32:31 +0300 Subject: [PATCH 14/71] Update lesson1.md --- lesson/lesson1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 2b5e449..a1b848e 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -54,6 +54,7 @@ - [Working with remote repositories](https://illustrated-git.readthedocs.org/en/latest/#working-with-remote-repositories) - [Базовый курс по обучению Git](https://www.youtube.com/playlist?list=PLIU76b8Cjem5B3sufBJ_KFTpKkMEvaTQR) (youtube) - [Git. Быстрый старт](https://www.youtube.com/watch?v=4-NX17Ip-xQ&list=PLmRNNqEA7JoM77hOJkPrLOfJQGizCLR3P) (youtube) + - [Подробное введение в работу с Git](https://tproger.ru/translations/beginner-git-cheatsheet/) ### Настройка проекта - Создайте на GitHub репозиторий с названием `basejava` From 47e96cd2c3df97400801a6d9b8d61b810601f428 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Fri, 16 Aug 2019 22:31:24 +0300 Subject: [PATCH 15/71] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 197623f..3d0033f 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,7 @@ - Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. ## Ресуры в сети +- [EduTools плагин от JetBrains для изучения Kotlin, Java, Python, Scala, ...](http://javaops.ru/view/story/story21#edutools) - [Руководство по Java Core](http://proselyte.net/tutorials/java-core/) - [Java. Базовый курс](https://stepik.org/course/Java-Базовый-курс-187) - intuit: Программирование на Java From 493a7bb6651bd1f12821a61eb4bc47e3a4f1d705 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Fri, 16 Aug 2019 22:42:34 +0300 Subject: [PATCH 16/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d0033f..36da323 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,6 @@ ## Ресуры в сети - [EduTools плагин от JetBrains для изучения Kotlin, Java, Python, Scala, ...](http://javaops.ru/view/story/story21#edutools) - [Руководство по Java Core](http://proselyte.net/tutorials/java-core/) -- [Java. Базовый курс](https://stepik.org/course/Java-Базовый-курс-187) +- [Java. Базовый курс (доступен также через плагин JetBrains EduTools)](https://stepik.org/course/Java-Базовый-курс-187) - intuit: Программирование на Java - Основы программирования на Java: учебное пособие From a2249f1042465ccadf73a5ffd00562970757e489 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 26 Feb 2020 22:47:01 +0300 Subject: [PATCH 17/71] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index a1b848e..df65dd3 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -10,7 +10,7 @@ ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) - [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) -- [Размеры проектов в количестве строк кода [eng]](https://medium.freecodecamp.com/the-biggest-codebases-in-history-a128bb3eea73) +- [Размеры проектов в количестве строк кода [eng]](https://www.freecodecamp.org/news/the-biggest-codebases-in-history-a128bb3eea73) - [Соглашения по оформлению кода [eng]](https://google.github.io/styleguide/javaguide.html) - [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) - [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) From f816603599eaa9f0cf8fd76a3623c7ece84488b2 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Fri, 28 Feb 2020 14:26:28 +0300 Subject: [PATCH 18/71] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index df65dd3..70e8122 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -40,7 +40,7 @@ - **Дополнительно:** - [Java version and vendor data analyzed 2017](https://plumbr.io/blog/java/java-version-and-vendor-data-analyzed-2017-edition) - [Most popular Java application servers: 2017 edition](https://plumbr.io/blog/java/most-popular-java-application-servers-2017-edition) - - [Понимаем основы Java garbage collection](https://ggenikus.github.io/blog/2014/05/04/gc) + - [Понимаем основы Java garbage collection](http://web.archive.org/web/20180831013112/https://ggenikus.github.io/blog/2014/05/04/gc) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) From 8c34e2789ef3afb53b676895d2a775e83ab86839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Wed, 4 Mar 2020 18:43:38 +0300 Subject: [PATCH 19/71] Update lesson1.md --- lesson/lesson1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 70e8122..a55bf6d 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -114,6 +114,8 @@ r1, r2, r3,..., rn, null, null,..., null 5. Не игнорируй подсказки IDEA (подсвечивает) 6. `Resume r` — давай переменным осмысленные имена, например `resume`. `r` допустимо в коротких циклах и лямбдах. 7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового +1. При реализации методов не используйте коллекции +1. Не меняйте сигнатуры методов в `ArrayStorage` # Дополнительно (как учиться программированию) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Вебинар "Быть программистом: от детства к зрелости"](https://www.youtube.com/watch?v=D5Hej0TyLaU) From 627eedf85cfd3065b3197cb8e18c164e380c54b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Tue, 19 May 2020 23:16:50 +0200 Subject: [PATCH 20/71] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index a55bf6d..2ba5579 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -60,7 +60,7 @@ - Создайте на GitHub репозиторий с названием `basejava` - Откройте консоль (терминал) у себя на компьютере - Наберите и запустите: `git` (по умолчанию при установке git заносится в PATH. Если он не находится, [занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль) -- Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` +- **Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git`. Реализацию дз выполняйте в рамках данной копии** - Перейдите в каталог проекта: `cd basejava` - Настройте git в локальном проекте на свой проект в GitHub: - `git remote -v` From 16e2af68b2d25e86b2fbddea13c705f2b86fb5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Wed, 8 Jul 2020 16:15:14 +0300 Subject: [PATCH 21/71] Update lesson1.md --- lesson/lesson1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 2ba5579..ae701b4 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -6,12 +6,12 @@ - Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) - Установите систему управления версиями [Git](http://git-scm.com/downloads) (опции по умолчанию) - Создайте аккаунт на [GitHub](https://github.com/). Для удобной навигации по файлам на GitHub можно установить расширение для браузера [Octotree](https://habrahabr.ru/post/223527/) -- Установите [IntelliJ IDEA](http://www.jetbrains.com/idea/download/index.html). **Пока нет базы данных и веб, можно работать с версией Community**. На версию Ultimate дается 30 дней пробного бесплатного использования (trial). На проектах каждый участник проектов получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев. +- Установите [IntelliJ IDEA](http://www.jetbrains.com/idea/download/index.html). **Пока нет базы данных и веб, можно работать с версией Community**. На версию Ultimate дается 30 дней пробного бесплатного использования (trial). На проектах каждый участник получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) - [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) - [Размеры проектов в количестве строк кода [eng]](https://www.freecodecamp.org/news/the-biggest-codebases-in-history-a128bb3eea73) -- [Соглашения по оформлению кода [eng]](https://google.github.io/styleguide/javaguide.html) +- [Руководство Google по форматированию кода на Java](https://topjava.ru/blog/google-java-style-guide) - [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) - [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) From 0b0ef3f49bd677fbd73f036c378d96fe321612f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Wed, 29 Jul 2020 02:40:23 +0300 Subject: [PATCH 22/71] Update README.md --- README.md | 181 ++++++++++++++++++++++++++---------------------------- 1 file changed, 87 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index 36da323..1fdcab2 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,52 @@ -# Курс BaseJava (обновленный и переработанный) - -## Разработка Web приложения "База данных резюме" - - используем: Java 8, IntelliJ IDEA, - GitHib/Git, Сервлеты, JSP, JSTL, Tomcat, JUnit, PostgreSQL, GSON, JAXB - - хранение резюме - - в памяти на основе массива, отсортированного массива, списка и ассоциированного массива (Map) - - в файловой системе (File API и Java 7 NIO File API) +# [Курс BaseJava (обновленный и переработанный)](http://javaops.ru/reg/basejava) + +## Разработка web-приложения "База данных резюме" + +В данном курсе вы создадите с нуля web-приложение, реализуя разные способы хранения резюме. Проект включает в себя следующее: + - **Технологии:** Java 8, GitHub/Git, JUnit, Logging, GSON, JAXB, SQL, PostgreSQL, Сервлеты, HTML, JSP, JSTL, Tomcat, Maven и многое другое + - **Различные способы реализации хранения резюме:** + - в сортированном и не сортированном массиве + - в коллекциях (List, Map) + - в файловой системе: + - с использованием File и Path API - в стандартной и кастомной сериализации Java - - в формате JSON (Google Gson) - - в формате XML (JAXB) - - в реляционной базе PostgreSQL - - деплой веб приложения - - в контейнер сервлетов Tomcat - - в облачный сервис Heroku + - в формате JSON ([Google Gson](https://en.wikipedia.org/wiki/Gson)) + - в формате XML ([JAXB](https://ru.wikipedia.org/wiki/Java_Architecture_for_XML_Binding)) + - в реляционной базе [PostgreSQL](https://ru.wikipedia.org/wiki/PostgreSQL) + - **Установку (деплой) web-приложения:** + - в контейнер сервлетов [Tomcat](https://ru.wikipedia.org/wiki/Apache_Tomcat) + - в облачный сервис [Heroku](https://ru.wikipedia.org/wiki/Heroku) -Приложение будет разрабатываться начиная со первого занятия, основываясь на базовых темах курса: -**объектная модель, коллекции, система ввода-вывода, работа с файлами, сериализация, работа с XML, JSON, SQL, персистентность в базу данных (PostgreSQL), сервлеты, HTML/JSP/JSTL, веб-контейнер Tomcat, модульные тесты JUnit, java.util.Logging, система контроля версий Git.** +> Любое знание стоит воспринимать как подобие семантического дерева: убедитесь в том, что понимаете фундаментальные принципы, то есть ствол и крупные ветки, прежде чем лезть в мелкие листья-детали. Иначе последним не на чем будет держаться -> Любое знание стоит воспринимать как подобие семантического дерева: убедитесь в том, что понимаете фундаментальные принципы, то есть ствол и крупные ветки, прежде чем лезть в мелкие листья-детали. Иначе последним не на чем будет держаться. +— Илон Маск -[*— Илон Маск](https://ru.wikipedia.org/wiki/Маск,_Илон) +### Изучите [бесплатный урок](lesson/lesson1.md). В конце урока находится домашнее задание, по которому можно оценить свой уровень готовности к проекту -# Изучайте [первое открытое занятие](lesson/lesson1.md). -### Внизу урока есть первое домашнее задание, по которому можно оценить свой уровень готовности к проекту. +## Программа курса -## Программа -### [Регистрация](http://javaops.ru/reg/basejava) -### Открытое занятие 1 +#### Занятие 1 (бесплатное) - Обзор курса и методики обучения - Подготовка и настройка рабочего окружения - Подходы, применяемые при разработке ПО - Обзор инструментов и технологий, используемых Java-разработчиками - - Введение в язык Java: история создания, JVM, JIT-компиляция + - Введение в язык Java: история создания, JDK, JVM, JRE, JIT-компиляция - Системы управления версиями. Git - Домашнее задание -### Занятие 2 +#### Занятие 2 + - Типы данных - Введение в объектно-ориентированное программирование - Принципы ООП - - Модификаторы доступа - - Классы-обертки - Классы и объекты + - Классы-обертки + - Модификаторы доступа + - Конструктор - Структура памяти java-программы: Heap (куча), Stack (стек) - - Типы данных - - Пакетная организация файлов + - Пакеты - Домашнее задание -### Занятие 3 +#### Занятие 3 - Разбор домашнего задания - Обзор суперкласса Object - Связь между equals() и hashCode() @@ -54,102 +54,97 @@ - Программирование с помощью интерфейсов - Абстрактные классы - Сложность алгоритмов - - Паттерн проектирования Шаблонный метод + - Паттерн проектирования Template Method - Домашнее задание -### Занятие 4 +#### Занятие 4 - Разбор домашнего задания + - Конструктор - Работа со строками: String, StringBuilder, StringBuffer - String literal pool - Исключения (Exceptions) - - Конструктор - Ключевые слова: this, super - Reflection - - Аннотации в Java 8 + - Аннотации - Введение в модульное тестирование. JUnit - Домашнее задание -### Занятие 5 +#### Занятие 5 - Разбор домашнего задания - - Иерархия классов Коллекций + - Коллекций. Иерархия классов - Списки (List) - Множества (Set) - Ассоциативные массивы (Map) - Введение в Iterator - - Тестирование коллекций - Домашнее задание -### Занятие 6 +#### Занятие 6 - Разбор домашнего задания - - Autoboxing and Unboxing - - Паттерн проектирования Итератор + - Паттерн проектирования Iterator + - Autoboxing и Unboxing - Вложенные классы - Внутренние классы - Локальные классы - Анонимные классы - - Введение в лямбды + - Введение в лямбда-выражения - Функциональный интерфейс - Домашнее задание -### Занятие 7 +#### Занятие 7 - Разбор домашнего задания - Дженерики (Generic) - - Введение в логирование. Log4J - - Стандартный логер - Java Logging API - - Паттерн проектирования - Синглтон - - Перечисляемые типы (Enum) + - Введение в логирование. Log4J, Java Logging API + - Паттерн проектирования Singleton + - Перечисления (Enum) - Объектная модель - Домашнее задание -### Занятие 8 +#### Занятие 8 - Разбор домашнего задания - Классы работы с датами: Date, Calendar, TimeZone - - Дата и время в Java 8 - - Внешние библиотеки: Joda Time library - - Работа с файловой системой: класс File - - try-with-resources + - Дата и время в Java 8+ + - File API + - Освобождение ресурсов: try-with-resources - Домашнее задание -### Занятие 9 +#### Занятие 9 - Разбор домашнего задания - Обзор пакета java.io - - Классы чтения/записи потоков: InputStream/OutputStream - - Паттерн проектирования Декоратор - - Работа с классами чтения/записи символов: Reader и Writer - - Сериализация + - Классы чтения/записи потоков: InputStream и OutputStream + - Паттерн проектирования Decorator + - Классы чтения/записи символов: Reader и Writer + - Сериализация объектов - Обзор пакета java.nio - - Введение в Java 8 Stream API + - Введение в Java 8+ Stream API - Домашнее задание -### Занятие 10 +#### Занятие 10 - Разбор домашнего задания - - Паттерн проектирования Стратегия - - Работа с XML - - Работа с JSON: Google GSON и Jackson - - Введение в REST - - DataInputStream/DataOutputStream - - Домашнее задание - -### Занятие 11 - - Процессы и потоки - - Синхронизация методов и блоков - - Закон Мура - - Закон Амдала + - Паттерн проектирования Strategy + - Работа с XML (JAXB) + - Работа с JSON (GSON) + - Классы чтения/записи примитивных типов: DataInputStream и DataOutputStream + - Домашнее задание + +#### Занятие 11 + - Многопоточность + - Закон Мура и Амдала + - Потоки. Синхронизация доступа - Обзор методов класса Object - Ленивая инициализация - Java Memory Model - - Взаимная блокировка + - Deadlock - Домашнее задание -### Занятие 12 +#### Занятие 12 - Разбор домашнего задания - - Обзор java.util.concurrent + - Обзор классов java.util.concurrent - Синхронизаторы - - ThreadLocal переменные + - ThreadLocal-переменные - Сравнение с обменом (Compare-and-swap) - Домашнее задание -### Занятие 13 +#### Занятие 13 - Разбор домашнего задания - Введение в реляционные базы данных - Язык SQL @@ -161,7 +156,7 @@ - Обзор JDBC-архитектуры - Домашнее задание -### Занятие 14 +#### Занятие 14 - Разбор домашнего задания - Операции соединения таблиц. JOIN - Транзакции @@ -170,40 +165,38 @@ - Установка и настройка контейнера сервлетов Tomcat - Домашнее задание -### Занятие 15 +#### Занятие 15 - Разбор домашнего задания - Введение в HTML - Основы протокола HTTP - Настройка web.xml - - Развертывание (деплой) web-приложения в Tomcat + - Деплой web-приложения в Tomcat - Сервлеты - Домашнее задание -### Занятие 16 +#### Занятие 16 - Разбор домашнего задания - Жизненный цикл сервлета - Создание динамических страниц. JSP - - Расширенные возможности JSP: JSTL + - Расширенные возможности JSP. JSTL - Redirect и Forward - - CRUD + - CRUD-операции - Домашнее задание -### Занятие 17 +#### Занятие 17 - Разбор домашнего задания - Деплой приложения в облачный сервис Heroku - Загрузка классов в Java. Classloader - Домашнее задание ## Рекомендуемые книги -- YAKOV FAIN: Программирование на Java для начинающих -- Книги по Java: от новичка до профессионала -- Джошуа Блох: Java. Эффективное программирование, 2-е издание -- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования -- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. - -## Ресуры в сети -- [EduTools плагин от JetBrains для изучения Kotlin, Java, Python, Scala, ...](http://javaops.ru/view/story/story21#edutools) -- [Руководство по Java Core](http://proselyte.net/tutorials/java-core/) -- [Java. Базовый курс (доступен также через плагин JetBrains EduTools)](https://stepik.org/course/Java-Базовый-курс-187) -- intuit: Программирование на Java -- Основы программирования на Java: учебное пособие +- [Яков Файн, "Программирование на Java для начинающих"](http://myflex.org/books/java4kids/java4kids.htm) +- [Книги по Java: от новичка до профессионала](https://proglib.io/p/java-books-2019/) +- [Джошуа Блох, "Java. Эффективное программирование, 3-е издание"](https://www.ozon.ru/context/detail/id/148627191/) +- [Роберт Мартин, "Чистый код"](https://www.ozon.ru/context/detail/id/142429922/) +- [Серия Head First, "Паттерны проектирования"](https://www.ozon.ru/context/detail/id/144233005/) +- [Вайсфельд Мэтт, "Объектно-ориентированный подход"](https://www.ozon.ru/context/detail/id/166375103/?stat=YW5fMQ%3D%3D) + +## Ресурсы в сети +- [EduTools плагин от JetBrains для изучения Kotlin, Java, Python, Scala и других языков](http://javaops.ru/view/story/story21#edutools) +- [JetBrains Academy — интерактивный учебный курс по Java](https://www.jetbrains.com/ru-ru/academy/) From 1a2dff2b2f384e1cd0fa700939775d054c5460c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Wed, 29 Jul 2020 03:14:34 +0300 Subject: [PATCH 23/71] Update lesson1.md --- lesson/lesson1.md | 131 ++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 73 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index ae701b4..f65d53a 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -1,86 +1,76 @@ # Первое занятие -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Видеообзор проекта Basejava](https://www.youtube.com/watch?v=0ydTRfKS9yY) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Видеообзор курса Basejava](https://www.youtube.com/watch?v=0ydTRfKS9yY) ### Подготовка рабочего окружения - Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) -- Установите систему управления версиями [Git](http://git-scm.com/downloads) (опции по умолчанию) -- Создайте аккаунт на [GitHub](https://github.com/). Для удобной навигации по файлам на GitHub можно установить расширение для браузера [Octotree](https://habrahabr.ru/post/223527/) -- Установите [IntelliJ IDEA](http://www.jetbrains.com/idea/download/index.html). **Пока нет базы данных и веб, можно работать с версией Community**. На версию Ultimate дается 30 дней пробного бесплатного использования (trial). На проектах каждый участник получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев +- Установите систему управления версиями [Git](http://git-scm.com/downloads) +- Создайте аккаунт на [GitHub](https://github.com/) +- Для удобной навигации по файлам на GitHub установите расширение для браузера [Octotree](https://habrahabr.ru/post/223527/) +- Установите [IntelliJ IDEA Community](http://www.jetbrains.com/idea/download/index.html) (Ultimate-версия понадобится позже, при работе с базой данных и web) +> Для версии Ultimate дается 30 дней бесплатного использования. Но в качестве подарка, каждому участнику курса, мы выдаем единоразово купон на 6 месяцев ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) - [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) -- [Размеры проектов в количестве строк кода [eng]](https://www.freecodecamp.org/news/the-biggest-codebases-in-history-a128bb3eea73) -- [Руководство Google по форматированию кода на Java](https://topjava.ru/blog/google-java-style-guide) +- [Подборка книг для руководителей в сфере IT](https://habr.com/ru/company/skyeng/blog/465215/) +- [Размеры проектов в количестве строк кода](https://www.freecodecamp.org/news/the-biggest-codebases-in-history-a128bb3eea73) +- [Соглашения по оформлению кода](https://topjava.ru/blog/google-java-style-guide) - [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) - [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) -- [Bash — шпаргалка для начинающих](https://tproger.ru/translations/bash-cheatsheet) -- **Обновление!!* - - [The State of Java in 2018](http://www.baeldung.com/java-in-2018) - - [Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) - - [Java Tools and Technologies Landscape Report 2016](https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/) - - [Java Tools and Technologies Landscape for 2014](http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014) -- **Дополнительно:** - - [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) +- [Популярность Java-технологий в 2019 году](https://topjava.ru/blog/sostoyanie-java-v-2019-godu) +- [Java Technology Report 2020](https://www.jrebel.com/blog/2020-java-technology-report) +- [The State of Developer Ecosystem 2020](https://www.jetbrains.com/lp/devecosystem-2020/java/) +- [JVM Ecosystem Report 2020](https://snyk.io/wp-content/uploads/jvm_2020.pdf) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) -- [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) (wiki) + +![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) + +- [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) +- Java [ME](http://ru.wikipedia.org/wiki/Java_Platform,_Micro_Edition), [SE](https://ru.wikipedia.org/wiki/Java_Platform,_Standard_Edition), [EE](http://ru.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) - [Что такое JDK? Введение в средства разработки Java](https://topjava.ru/blog/what-is-the-jdk) - [Что такое JRE? Введение в среду выполнения Java](https://topjava.ru/blog/what-is-the-jre) - [Что такое Java? История создания](http://www.intuit.ru/studies/courses/16/16/lecture/27105) - [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) - -![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) - -- [ME](http://ru.wikipedia.org/wiki/Java_Platform,_Micro_Edition), [SE](https://ru.wikipedia.org/wiki/Java_Platform,_Standard_Edition), [EE](http://ru.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) (wiki) - [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh/) (используем на курсе [MasterJava](https://github.com/JavaWebinar/masterjava#Занятие-2)) -- [Oracle Java8 Home](http://docs.oracle.com/javase/8/docs/index.html) -- **Дополнительно:** - - [Java version and vendor data analyzed 2017](https://plumbr.io/blog/java/java-version-and-vendor-data-analyzed-2017-edition) - - [Most popular Java application servers: 2017 edition](https://plumbr.io/blog/java/most-popular-java-application-servers-2017-edition) - - [Понимаем основы Java garbage collection](http://web.archive.org/web/20180831013112/https://ggenikus.github.io/blog/2014/05/04/gc) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) ![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) - - [Система управления версиями](https://ru.wikipedia.org/wiki/Система_управления_версиями) (wiki) - - [Сравнение разных VCS](https://biz30.timedoctor.com/ru/cистема-контроля-версий/) - - [Git обучалка](https://githowto.com/ru) - - [Интерактивная Git обучалка (в настройках выберите русский язык)](http://learngitbranching.js.org) - - [Официальная книга про Git](https://git-scm.com/book/ru/v2) - - [Working with remote repositories](https://illustrated-git.readthedocs.org/en/latest/#working-with-remote-repositories) - - [Базовый курс по обучению Git](https://www.youtube.com/playlist?list=PLIU76b8Cjem5B3sufBJ_KFTpKkMEvaTQR) (youtube) - - [Git. Быстрый старт](https://www.youtube.com/watch?v=4-NX17Ip-xQ&list=PLmRNNqEA7JoM77hOJkPrLOfJQGizCLR3P) (youtube) - - [Подробное введение в работу с Git](https://tproger.ru/translations/beginner-git-cheatsheet/) +- [Система управления версиями (VCS)](https://ru.wikipedia.org/wiki/Система_управления_версиями) +- [Сравнение разных VCS](https://biz30.timedoctor.com/ru/cистема-контроля-версий/) +- [Видео-уроки по Git](https://www.youtube.com/playlist?list=PLDyvV36pndZHkDRik6kKF6gSb0N0W995h) +- Интерактивные Git-обучалки: [1](https://githowto.com/ru), [2](http://learngitbranching.js.org) +- [Официальная книга по Git](https://git-scm.com/book/ru/v2) ### Настройка проекта - Создайте на GitHub репозиторий с названием `basejava` -- Откройте консоль (терминал) у себя на компьютере -- Наберите и запустите: `git` (по умолчанию при установке git заносится в PATH. Если он не находится, [занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль) -- **Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git`. Реализацию дз выполняйте в рамках данной копии** -- Перейдите в каталог проекта: `cd basejava` -- Настройте git в локальном проекте на свой проект в GitHub: - - `git remote -v` - - `git remote set-url origin url_на_твой_basejava-репозиторий.git` - настройка pull - - `git remote set-url --push origin url_на_твой_basejava-репозиторий.git` - настройка push - - `git push -u origin master` +- Откройте консоль у себя на компьютере (в папке, где планируете разместить проект) и выполните следующее: + - **Скачайте копию проекта с заранее заданными классами: `git clone https://github.com/JavaOps/basejava.git`. Реализацию дз выполняйте в рамках данной копии** + - Перейдите в каталог проекта: `cd basejava` + - Настройте git у себя на компьютере на свой репозиторий в GitHub: + - `git remote set-url origin url_на_ваш_basejava-репозиторий.git` — настройка pull + - `git remote set-url --push origin url_на_ваш_basejava-репозиторий.git` — настройка push + - `git remote -v` — удостоверьтесь, что команда выводит ссылки на ваш удаленный репозиторий + - `git push -u origin master` — [устанавливаем связь](https://qna.habr.com/q/118865) между локальной и удаленной веткой master ## Домашнее задание HW1 -- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, который вы клонировали ранее к себе на компьютер: +- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, который вы скачали ранее к себе на компьютер: -![newproject](https://user-images.githubusercontent.com/29703461/38273513-d1f7ce52-3794-11e8-829c-305212c25be7.png) +![newproject](https://user-images.githubusercontent.com/29703461/88058015-95008580-cb6b-11ea-9b7c-65843b859988.png) -![next](https://user-images.githubusercontent.com/29703461/38273546-e712a6fe-3794-11e8-9850-29287b46a8a0.png) +![next](https://user-images.githubusercontent.com/29703461/88057628-055ad700-cb6b-11ea-9c59-72bb538e2541.png) -![next1](https://user-images.githubusercontent.com/29703461/38273584-00e07dc2-3795-11e8-9006-3109f949cf33.png) +![next1](https://user-images.githubusercontent.com/29703461/88058925-d2b1de00-cb6c-11ea-9d0b-83c771899457.png) -![finish](https://user-images.githubusercontent.com/29703461/38275669-3e621614-379b-11e8-8b3a-8e0a3ad4c65c.png) +![finish](https://user-images.githubusercontent.com/29703461/88059306-579cf780-cb6d-11ea-8094-bbf87474a127.png) -- Реализуйте класс `ArrayStorage`, организовав хранение резюме на основе массива с методами `save, get, delete, size, clear, getAll` -- Храните все резюме в начале `storage` (без дырок в виде `null`), чтобы не перебирать каждый раз все 10000 элементов +- Реализуйте методы `save, get, delete, clear, getAll, size` в классе `ArrayStorage`, организовав хранение резюме в массиве +- Храните все резюме в начале `storage` (без пустот в виде `null`), чтобы не перебирать каждый раз все 10_000 элементов +- При реализации метода `delete` учитывайте, что после удаления резюме между оставшимися резюме не должно быть пустых ячеек, заполненных null ``` Схема хранения резюме в массиве storage (в элементах от 0 до size-1 отсутствуют null): @@ -88,41 +78,36 @@ r1, r2, r3,..., rn, null, null,..., null <----- size -----> <------- storage.length (10000) -------> ``` -- Протестируйте вашу реализацию с помощью классов `MainArray.main()` и `MainTestArrayStorage.main()` +- Проверьте вашу реализацию с помощью классов `MainArray.main()` и `MainTestArrayStorage.main()` - Изучите дополнительные материалы по IntelliJ IDEA: - - [Idea Wiki](https://github.com/JavaOPs/topjava/wiki/IDEA) ([поставьте кодировку UTF-8](https://github.com/JavaOPs/topjava/wiki/IDEA#Поставить-кодировку-utf-8), [поменяйте шрифт по умолчанию на DejaVu](https://github.com/JavaOPs/topjava/wiki/IDEA#Поменять-фонт-по-умолчанию-dejavu)) - - [Руководство пользователя IntelliJ IDEA. Отладчик](http://info.javarush.ru/idea_help/2014/01/22/Руководство-пользователя-IntelliJ-IDEA-Отладчик-.html) - - [Эффективная работа с кодом в IntelliJ IDEA](https://www.youtube.com/watch?v=tpv5n2jWHlw) (youtube) - - [Эффективная работа в IDEA](https://www.youtube.com/watch?v=_rj7dx6c5R8) (youtube) + - [Idea Wiki](https://github.com/JavaOPs/topjava/wiki/IDEA) + - [Отладка Java кода в IDEA. Основные возможности отладчика](https://youtu.be/Z1BQsf0A4xY) + - [Эффективная работа с кодом в IntelliJ IDEA](https://www.youtube.com/watch?v=tpv5n2jWHlw) + - [Эффективная работа в IDEA](https://www.youtube.com/watch?v=_rj7dx6c5R8) ### Вопросы по HW1 > Не могу запустить программу, да и рядом с классами появился какой-то значок + ![badsrc](https://user-images.githubusercontent.com/29703461/38277015-9cd9155e-379f-11e8-9cd4-a9182a005e9a.png) - Проблема в том, что IDEA неправильно "воспринимает" папку `src`. Для ее решения необходимо нажать `ПКМ на папке src -> выбрать Mark Directory as -> Sources Root` - > Что такое `null`? - -[Что такое null в Java?](http://qaru.site/questions/1960/what-is-null-in-java) (оригинал: [What is null in Java? -](https://stackoverflow.com/questions/2707322/what-is-null-in-java)) - ### Замечания по выполнению HW1 -1. Все резюме в хранилище имеют уникальный `uuid`, что исключает повторы. Cортировка по `uuid` не требуется -2. Давайте осмысленные комментарии коммитам -3. Перед каждым коммитом не забывайте пользоваться сочетанием клавиш `Ctrl + Alt + L` (автоматическое форматирование кода) -4. Не злоупотребляйте пустыми строками. Они используются нечасто для логического отделения больших кусков кода. -5. Удаляйте неиспользуемые импорты (`Ctrl + Alt + O`) -5. Не игнорируй подсказки IDEA (подсвечивает) -6. `Resume r` — давай переменным осмысленные имена, например `resume`. `r` допустимо в коротких циклах и лямбдах. -7. В методе `clear()` обнуление массива предполагает именно обнуление (null), а не создание нового +1. Все резюме в хранилище имеют уникальный `uuid`, что исключает повторы. Сортировка по `uuid` не требуется +1. Давайте осмысленные комментарии коммитам +1. Перед каждым коммитом не забывайте пользоваться сочетанием клавиш `Ctrl + Alt + L` (автоматическое форматирование кода) +1. Удаляйте в классах неиспользуемые импорты (`Ctrl + Alt + O`) +1. Не игнорируй подсказки IDEA (подсвечивает) +1. В методе `clear()` обнуление массива предполагает обнуление (null) ячеек, где хранятся Resume, а не создание нового или присваивание ему null 1. При реализации методов не используйте коллекции 1. Не меняйте сигнатуры методов в `ArrayStorage` +1. Не добавляйте в `Resume` новые поля +1. Resume r — давайте переменным осмысленные имена, например resume. r допустимо в коротких циклах и лямбда-выражениях -# Дополнительно (как учиться программированию) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Вебинар "Быть программистом: от детства к зрелости"](https://www.youtube.com/watch?v=D5Hej0TyLaU) - [Слайды вебинара](https://docs.google.com/presentation/d/1YwtCCZsaGMdl-V15kTDHiJxiS52IAl-qqheNPpiNr54/) -## Советы по обучению - - Учись грамотно формулировать проблему. Проблема "у меня не работает" может иметь тысячи причин. В процессе формулирования очень часто приходит ее решение. - - Учись инвестигировать проблему. Внимательное чтение логов и умение дебажить - основные навыки разработчика. В логах надо читать верх самого нижнего эксепшена - там причина всей портянки. - - Грамотно уделяй время каждой проблеме. Две крайности - сразу бросаться за помощью и бится нам ней часами. Пробуй решить ее сам и в зависимости от проблемы выделяй на это разумное время. - - Получай в процессе решения обратную связь - в том ли направлении ты идешь. +### Советы по обучению + - Учитесь грамотно формулировать проблему: "у меня не работает" может иметь тысячи причин. В процессе формулирования часто приходит ее решение + - Учитесь исследовать проблему. Внимательное чтение логов и умение дебажить — основные навыки разработчика. В логах необходимо читать верхнюю часть самого нижнего иксепшена. Именно там находится причина возникшей ошибки + - Грамотно распределяйте время для каждой проблемы. Не впадайте в крайности: сразу бросаться за помощью или биться над ней часами. Подходите к ее решению разумно + - Получайте в процессе решения обратную связь, что бы убедиться в правильности выбранного направления - [Советы новичкам](http://blog.csssr.ru/2016/09/19/how-to-be-a-beginner-developer) From b0183ce136fd9b2ff2231e83843ec55d51de03eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Wed, 29 Jul 2020 03:17:50 +0300 Subject: [PATCH 24/71] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index f65d53a..3bd9043 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -11,7 +11,7 @@ > Для версии Ultimate дается 30 дней бесплатного использования. Но в качестве подарка, каждому участнику курса, мы выдаем единоразово купон на 6 месяцев ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) -- [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) +- [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) - [Подборка книг для руководителей в сфере IT](https://habr.com/ru/company/skyeng/blog/465215/) - [Размеры проектов в количестве строк кода](https://www.freecodecamp.org/news/the-biggest-codebases-in-history-a128bb3eea73) - [Соглашения по оформлению кода](https://topjava.ru/blog/google-java-style-guide) From 781170798d01ac1e6bf311583e65e91a4ebb38ae Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 17 Dec 2020 17:57:27 +0300 Subject: [PATCH 25/71] Update lesson1.md --- lesson/lesson1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 3bd9043..b6a9812 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -41,6 +41,7 @@ ![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) - [Система управления версиями (VCS)](https://ru.wikipedia.org/wiki/Система_управления_версиями) +- [Введение в Git: от установки до основных команд](https://tproger.ru/translations/beginner-git-cheatsheet/) - [Сравнение разных VCS](https://biz30.timedoctor.com/ru/cистема-контроля-версий/) - [Видео-уроки по Git](https://www.youtube.com/playlist?list=PLDyvV36pndZHkDRik6kKF6gSb0N0W995h) - Интерактивные Git-обучалки: [1](https://githowto.com/ru), [2](http://learngitbranching.js.org) From d91ae923417cb9819a313aceec4177cbdc09885d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Fri, 5 Mar 2021 13:35:08 +0300 Subject: [PATCH 26/71] Update MainArray.java --- src/MainArray.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index b1cb33b..063364d 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -13,7 +13,7 @@ public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Resume r; while (true) { - System.out.print("Введите одну из команд - (list | save uuid | delete uuid | get uuid | clear | exit): "); + System.out.print("Введите одну из команд - (list | size | save uuid | delete uuid | get uuid | clear | exit): "); String[] params = reader.readLine().trim().toLowerCase().split(" "); if (params.length < 1 || params.length > 2) { System.out.println("Неверная команда."); @@ -68,4 +68,4 @@ static void printAll() { } System.out.println("----------------------------"); } -} \ No newline at end of file +} From 481ff68f22d937588df29bf0dc24b2abf30387de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Sat, 13 Mar 2021 11:57:30 +0300 Subject: [PATCH 27/71] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index b6a9812..7ae19ca 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -20,7 +20,7 @@ ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) - [Популярность Java-технологий в 2019 году](https://topjava.ru/blog/sostoyanie-java-v-2019-godu) -- [Java Technology Report 2020](https://www.jrebel.com/blog/2020-java-technology-report) +- [Java Technology Report 2021](https://www.jrebel.com/blog/2021-java-technology-report) - [The State of Developer Ecosystem 2020](https://www.jetbrains.com/lp/devecosystem-2020/java/) - [JVM Ecosystem Report 2020](https://snyk.io/wp-content/uploads/jvm_2020.pdf) From deb19274caf36b67e718cf3a3195daf01a488be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Mon, 28 Jun 2021 19:32:51 +0300 Subject: [PATCH 28/71] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 7ae19ca..5995d08 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -22,7 +22,7 @@ - [Популярность Java-технологий в 2019 году](https://topjava.ru/blog/sostoyanie-java-v-2019-godu) - [Java Technology Report 2021](https://www.jrebel.com/blog/2021-java-technology-report) - [The State of Developer Ecosystem 2020](https://www.jetbrains.com/lp/devecosystem-2020/java/) -- [JVM Ecosystem Report 2020](https://snyk.io/wp-content/uploads/jvm_2020.pdf) +- [JVM Ecosystem Report 2021](https://snyk.io/jvm-ecosystem-report-2021/) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) From 5a55bf6cd910d58008594c2110993abf87995348 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 27 Sep 2021 00:08:55 +0300 Subject: [PATCH 29/71] Update lesson1.md --- lesson/lesson1.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 5995d08..8f421ce 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -10,7 +10,7 @@ - Установите [IntelliJ IDEA Community](http://www.jetbrains.com/idea/download/index.html) (Ultimate-версия понадобится позже, при работе с базой данных и web) > Для версии Ultimate дается 30 дней бесплатного использования. Но в качестве подарка, каждому участнику курса, мы выдаем единоразово купон на 6 месяцев -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/file/d/0B_4NpoQW1xfpVjZUTEpvVUN1TTA/view?usp=sharing&resourcekey=0-hnn1HIBU3WIuDMVuQAxA8w) - [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) - [Подборка книг для руководителей в сфере IT](https://habr.com/ru/company/skyeng/blog/465215/) - [Размеры проектов в количестве строк кода](https://www.freecodecamp.org/news/the-biggest-codebases-in-history-a128bb3eea73) @@ -18,13 +18,13 @@ - [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) - [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M/view?usp=sharing&resourcekey=0-Uw_lRGW12YNjwY7phXzVdg) - [Популярность Java-технологий в 2019 году](https://topjava.ru/blog/sostoyanie-java-v-2019-godu) - [Java Technology Report 2021](https://www.jrebel.com/blog/2021-java-technology-report) - [The State of Developer Ecosystem 2020](https://www.jetbrains.com/lp/devecosystem-2020/java/) - [JVM Ecosystem Report 2021](https://snyk.io/jvm-ecosystem-report-2021/) -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/file/d/0B_4NpoQW1xfpTU5SSElhUjlGNnc/view?usp=sharing&resourcekey=0-DOyRoGhREx2kvKwAKTOlYg) ![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) @@ -36,7 +36,7 @@ - [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) - [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh/) (используем на курсе [MasterJava](https://github.com/JavaWebinar/masterjava#Занятие-2)) -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s/edit?resourcekey=0-6scb0PBj2A3Oqf6rsU2egQ) ![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) From f2df92cd928222c64c862c625327e13de546c588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Sun, 10 Apr 2022 16:35:05 +0300 Subject: [PATCH 30/71] add a link to the new design --- lesson/lesson1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 8f421ce..0a85be6 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -1,5 +1,7 @@ # Первое занятие +## [Демо разрабатываемого приложения](https://basejava.herokuapp.com/resume?theme=light) + ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Видеообзор курса Basejava](https://www.youtube.com/watch?v=0ydTRfKS9yY) ### Подготовка рабочего окружения From 58b491c0a8ea60fdfa25c69683f46ea967c490fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Fri, 19 Aug 2022 20:16:47 +0300 Subject: [PATCH 31/71] Update lesson1.md --- lesson/lesson1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 0a85be6..ce6414a 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -37,6 +37,7 @@ - [Что такое Java? История создания](http://www.intuit.ru/studies/courses/16/16/lecture/27105) - [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) - [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh/) (используем на курсе [MasterJava](https://github.com/JavaWebinar/masterjava#Занятие-2)) +- [Руководство по массивам в Java](https://topjava.ru/blog/rukovodstvo-po-massivam-v-java-ch1) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s/edit?resourcekey=0-6scb0PBj2A3Oqf6rsU2egQ) From 12835d1271aef6e185ae0b5c4bba2bf989a0c226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A7=D0=B8=D0=BC=D0=B0=D0=B5=D0=B2=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D0=BC?= Date: Wed, 2 Nov 2022 19:46:00 +0300 Subject: [PATCH 32/71] Update lesson1.md --- lesson/lesson1.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index ce6414a..73fc452 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -62,15 +62,9 @@ - `git push -u origin master` — [устанавливаем связь](https://qna.habr.com/q/118865) между локальной и удаленной веткой master ## Домашнее задание HW1 -- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, который вы скачали ранее к себе на компьютер: +- Откройте в IntelliJ IDEA ваш проект, выбрав каталог `basejava`, который вы скачали ранее к себе на компьютер: -![newproject](https://user-images.githubusercontent.com/29703461/88058015-95008580-cb6b-11ea-9b7c-65843b859988.png) - -![next](https://user-images.githubusercontent.com/29703461/88057628-055ad700-cb6b-11ea-9c59-72bb538e2541.png) - -![next1](https://user-images.githubusercontent.com/29703461/88058925-d2b1de00-cb6c-11ea-9d0b-83c771899457.png) - -![finish](https://user-images.githubusercontent.com/29703461/88059306-579cf780-cb6d-11ea-8094-bbf87474a127.png) +![Screenshot_5](https://user-images.githubusercontent.com/29703461/199550057-fce7cf3c-7040-422f-b490-7b85b47ae952.png) - Реализуйте методы `save, get, delete, clear, getAll, size` в классе `ArrayStorage`, организовав хранение резюме в массиве - Храните все резюме в начале `storage` (без пустот в виде `null`), чтобы не перебирать каждый раз все 10_000 элементов From a6387875979dedf3f5e9929654c0253650bf56ed Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:31:16 +0300 Subject: [PATCH 33/71] test --- "\320\271\321\206\321\203.txt" | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 "\320\271\321\206\321\203.txt" diff --git "a/\320\271\321\206\321\203.txt" "b/\320\271\321\206\321\203.txt" new file mode 100644 index 0000000..e69de29 From 17b15688a2ff4e5e5765e628d92a8322c64de254 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Thu, 22 Dec 2022 21:14:15 +0300 Subject: [PATCH 34/71] =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D1=8B=20001?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ArrayStorage.java | 33 +++++++++++++++++++++++++++++++-- "\320\271\321\206\321\203.txt" | 0 2 files changed, 31 insertions(+), 2 deletions(-) delete mode 100644 "\320\271\321\206\321\203.txt" diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java index 7aff038..1a18db7 100644 --- a/src/ArrayStorage.java +++ b/src/ArrayStorage.java @@ -1,30 +1,59 @@ +import java.util.Arrays; + /** * Array based storage for Resumes */ public class ArrayStorage { Resume[] storage = new Resume[10000]; + private int lenght = 0; void clear() { + for (int i = 0; i <= lenght; i++) { + storage[i] = null; + } + lenght = 0; } void save(Resume r) { + storage[lenght++] = r; } Resume get(String uuid) { + int i = getPosition(uuid); + if (i >= 0) { + return storage[i]; + } return null; } void delete(String uuid) { + int i = getPosition(uuid); + for (; i < lenght; i++) { + storage[i] = storage[i + 1]; + } + if (i > 0) { + storage[lenght] = null; + } + lenght--; } /** * @return array, contains only Resumes in storage (without null) */ Resume[] getAll() { - return new Resume[0]; + return Arrays.copyOf(storage, lenght); } int size() { - return 0; + return lenght; + } + + private int getPosition(String uuid) { + for (int i = 0; i < lenght; i++) { + if (storage[i].uuid.equals(uuid)) { + return i; + } + } + return -1; } } diff --git "a/\320\271\321\206\321\203.txt" "b/\320\271\321\206\321\203.txt" deleted file mode 100644 index e69de29..0000000 From 44ba6fc5e0b9d64b8b57ca37315d42b226e02188 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Thu, 22 Dec 2022 23:02:30 +0300 Subject: [PATCH 35/71] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B9=20002?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ArrayStorage.java | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java index 1a18db7..4dce254 100644 --- a/src/ArrayStorage.java +++ b/src/ArrayStorage.java @@ -5,51 +5,48 @@ */ public class ArrayStorage { Resume[] storage = new Resume[10000]; - private int lenght = 0; + private int size; void clear() { - for (int i = 0; i <= lenght; i++) { + for (int i = 0; i < size; i++) { storage[i] = null; } - lenght = 0; + size = 0; } void save(Resume r) { - storage[lenght++] = r; + storage[size++] = r; } Resume get(String uuid) { - int i = getPosition(uuid); - if (i >= 0) { - return storage[i]; - } - return null; + int index = findIndex(uuid); + return (index >= 0) ? storage[index] : null; } void delete(String uuid) { - int i = getPosition(uuid); - for (; i < lenght; i++) { + int i = findIndex(uuid); + for (; i < size; i++) { storage[i] = storage[i + 1]; } if (i > 0) { - storage[lenght] = null; + storage[size] = null; + size--; } - lenght--; } /** * @return array, contains only Resumes in storage (without null) */ Resume[] getAll() { - return Arrays.copyOf(storage, lenght); + return Arrays.copyOf(storage, size); } int size() { - return lenght; + return size; } - private int getPosition(String uuid) { - for (int i = 0; i < lenght; i++) { + private int findIndex(String uuid) { + for (int i = 0; i < size; i++) { if (storage[i].uuid.equals(uuid)) { return i; } From 4a84ab5f4ed60d5229b4721ad17a3f4e70906a7b Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:05:59 +0300 Subject: [PATCH 36/71] HW02 002 --- src/ArrayStorage.java | 56 ------------ src/com/learnjava/array/ArrayStorage.java | 86 +++++++++++++++++++ src/{ => com/learnjava/array}/MainArray.java | 2 + .../array}/MainTestArrayStorage.java | 4 + src/{ => com/learnjava/resume}/Resume.java | 3 +- 5 files changed, 94 insertions(+), 57 deletions(-) delete mode 100644 src/ArrayStorage.java create mode 100644 src/com/learnjava/array/ArrayStorage.java rename src/{ => com/learnjava/array}/MainArray.java (97%) rename src/{ => com/learnjava/array}/MainTestArrayStorage.java (89%) rename src/{ => com/learnjava/resume}/Resume.java (74%) diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java deleted file mode 100644 index 4dce254..0000000 --- a/src/ArrayStorage.java +++ /dev/null @@ -1,56 +0,0 @@ -import java.util.Arrays; - -/** - * Array based storage for Resumes - */ -public class ArrayStorage { - Resume[] storage = new Resume[10000]; - private int size; - - void clear() { - for (int i = 0; i < size; i++) { - storage[i] = null; - } - size = 0; - } - - void save(Resume r) { - storage[size++] = r; - } - - Resume get(String uuid) { - int index = findIndex(uuid); - return (index >= 0) ? storage[index] : null; - } - - void delete(String uuid) { - int i = findIndex(uuid); - for (; i < size; i++) { - storage[i] = storage[i + 1]; - } - if (i > 0) { - storage[size] = null; - size--; - } - } - - /** - * @return array, contains only Resumes in storage (without null) - */ - Resume[] getAll() { - return Arrays.copyOf(storage, size); - } - - int size() { - return size; - } - - private int findIndex(String uuid) { - for (int i = 0; i < size; i++) { - if (storage[i].uuid.equals(uuid)) { - return i; - } - } - return -1; - } -} diff --git a/src/com/learnjava/array/ArrayStorage.java b/src/com/learnjava/array/ArrayStorage.java new file mode 100644 index 0000000..50c918c --- /dev/null +++ b/src/com/learnjava/array/ArrayStorage.java @@ -0,0 +1,86 @@ +package com.learnjava.array; + +import com.learnjava.resume.Resume; + +import java.util.Arrays; + +/** + * Array based storage for Resumes + */ +public class ArrayStorage { + private static final int maxCap = 10000; + Resume[] storage = new Resume[maxCap]; + private int size; + + void clear() { + for (int i = 0; i < size; i++) { + storage[i] = null; + } + size = 0; + } + + void save(Resume r) { + if (size + 1 > maxCap) { + System.out.println("ERROR in method \"save\": maximum capacity reached"); + } + int i = findIndex(r.uuid); + if (i < 0) { + storage[size++] = r; + } else { + System.out.println("ERROR in method \"save\": " + r.uuid + " already exists"); + } + } + + Resume get(String uuid) { + int i = findIndex(uuid); + if (i < 0) { + System.out.println("ERROR in method \"update\": " + uuid + " not found"); + return null; + } + return storage[i]; + } + + void update(Resume r) { + int i = findIndex(r.uuid); + if (i < 0) { + System.out.println("ERROR in method \"update\": " + r.uuid + " not found"); + return; + } + storage[i] = r; + } + + void delete(String uuid) { + int i = findIndex(uuid); + if (i < 0) { + System.out.println("ERROR in method \"delete\": " + uuid + " not found"); + return; + } + for (; i < size; i++) { + storage[i] = storage[i + 1]; + } + if (i > 0) { + storage[size] = null; + size--; + } + } + + /** + * @return array, contains only Resumes in storage (without null) + */ + Resume[] getAll() { + return Arrays.copyOf(storage, size); + } + + int size() { + return size; + } + + private int findIndex(String uuid) { + for (int i = 0; i < size; i++) { + if (storage[i].uuid.equals(uuid)) { + return i; + } + } + return -1; + } +} diff --git a/src/MainArray.java b/src/com/learnjava/array/MainArray.java similarity index 97% rename from src/MainArray.java rename to src/com/learnjava/array/MainArray.java index 063364d..fee21c2 100644 --- a/src/MainArray.java +++ b/src/com/learnjava/array/MainArray.java @@ -1,3 +1,5 @@ +package com.learnjava.array; +import com.learnjava.resume.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; diff --git a/src/MainTestArrayStorage.java b/src/com/learnjava/array/MainTestArrayStorage.java similarity index 89% rename from src/MainTestArrayStorage.java rename to src/com/learnjava/array/MainTestArrayStorage.java index b15b81e..4aa800b 100644 --- a/src/MainTestArrayStorage.java +++ b/src/com/learnjava/array/MainTestArrayStorage.java @@ -1,3 +1,5 @@ +package com.learnjava.array; +import com.learnjava.resume.*; /** * Test for your ArrayStorage implementation */ @@ -15,6 +17,8 @@ public static void main(String[] args) { ARRAY_STORAGE.save(r1); ARRAY_STORAGE.save(r2); ARRAY_STORAGE.save(r3); + ARRAY_STORAGE.save(r3); + ARRAY_STORAGE.update(r3); System.out.println("Get r1: " + ARRAY_STORAGE.get(r1.uuid)); System.out.println("Size: " + ARRAY_STORAGE.size()); diff --git a/src/Resume.java b/src/com/learnjava/resume/Resume.java similarity index 74% rename from src/Resume.java rename to src/com/learnjava/resume/Resume.java index 8de4e4b..3fdb0e7 100644 --- a/src/Resume.java +++ b/src/com/learnjava/resume/Resume.java @@ -1,10 +1,11 @@ +package com.learnjava.resume; /** * Initial resume class */ public class Resume { // Unique identifier - String uuid; + public String uuid; @Override public String toString() { From 48784c9831f3ceca69f4315bbcdb4f38fdb330be Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Wed, 14 Jun 2023 15:45:25 +0300 Subject: [PATCH 37/71] =?UTF-8?q?HW02=20003=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/{array => }/MainArray.java | 5 +- .../{array => }/MainTestArrayStorage.java | 5 +- .../learnjava/{resume => model}/Resume.java | 2 +- .../{array => storage}/ArrayStorage.java | 56 +++++++++---------- 4 files changed, 33 insertions(+), 35 deletions(-) rename src/com/learnjava/{array => }/MainArray.java (96%) rename src/com/learnjava/{array => }/MainTestArrayStorage.java (91%) rename src/com/learnjava/{resume => model}/Resume.java (85%) rename src/com/learnjava/{array => storage}/ArrayStorage.java (56%) diff --git a/src/com/learnjava/array/MainArray.java b/src/com/learnjava/MainArray.java similarity index 96% rename from src/com/learnjava/array/MainArray.java rename to src/com/learnjava/MainArray.java index fee21c2..325d8bb 100644 --- a/src/com/learnjava/array/MainArray.java +++ b/src/com/learnjava/MainArray.java @@ -1,5 +1,6 @@ -package com.learnjava.array; -import com.learnjava.resume.*; +package com.learnjava; +import com.learnjava.model.*; +import com.learnjava.storage.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; diff --git a/src/com/learnjava/array/MainTestArrayStorage.java b/src/com/learnjava/MainTestArrayStorage.java similarity index 91% rename from src/com/learnjava/array/MainTestArrayStorage.java rename to src/com/learnjava/MainTestArrayStorage.java index 4aa800b..2d2a2f1 100644 --- a/src/com/learnjava/array/MainTestArrayStorage.java +++ b/src/com/learnjava/MainTestArrayStorage.java @@ -1,5 +1,6 @@ -package com.learnjava.array; -import com.learnjava.resume.*; +package com.learnjava; +import com.learnjava.storage.ArrayStorage; +import com.learnjava.model.*; /** * Test for your ArrayStorage implementation */ diff --git a/src/com/learnjava/resume/Resume.java b/src/com/learnjava/model/Resume.java similarity index 85% rename from src/com/learnjava/resume/Resume.java rename to src/com/learnjava/model/Resume.java index 3fdb0e7..fa6e782 100644 --- a/src/com/learnjava/resume/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -1,4 +1,4 @@ -package com.learnjava.resume; +package com.learnjava.model; /** * Initial resume class */ diff --git a/src/com/learnjava/array/ArrayStorage.java b/src/com/learnjava/storage/ArrayStorage.java similarity index 56% rename from src/com/learnjava/array/ArrayStorage.java rename to src/com/learnjava/storage/ArrayStorage.java index 50c918c..fde52d9 100644 --- a/src/com/learnjava/array/ArrayStorage.java +++ b/src/com/learnjava/storage/ArrayStorage.java @@ -1,6 +1,6 @@ -package com.learnjava.array; +package com.learnjava.storage; -import com.learnjava.resume.Resume; +import com.learnjava.model.Resume; import java.util.Arrays; @@ -8,30 +8,30 @@ * Array based storage for Resumes */ public class ArrayStorage { - private static final int maxCap = 10000; - Resume[] storage = new Resume[maxCap]; + private static final int STORAGE_LIMIT = 10000; + protected final Resume[] storage = new Resume[STORAGE_LIMIT]; private int size; - void clear() { - for (int i = 0; i < size; i++) { - storage[i] = null; - } + public void clear() { + Arrays.fill(storage, null); size = 0; } - void save(Resume r) { - if (size + 1 > maxCap) { + public void save(Resume r) { + + if (size + 1 > STORAGE_LIMIT) { System.out.println("ERROR in method \"save\": maximum capacity reached"); - } - int i = findIndex(r.uuid); - if (i < 0) { - storage[size++] = r; } else { - System.out.println("ERROR in method \"save\": " + r.uuid + " already exists"); + int i = findIndex(r.uuid); + if (i > 0) { + System.out.println("ERROR in method \"save\": " + r.uuid + " already exists"); + } else { + storage[size++] = r; + } } } - Resume get(String uuid) { + public Resume get(String uuid) { int i = findIndex(uuid); if (i < 0) { System.out.println("ERROR in method \"update\": " + uuid + " not found"); @@ -40,38 +40,34 @@ Resume get(String uuid) { return storage[i]; } - void update(Resume r) { - int i = findIndex(r.uuid); + public void update(Resume resume) { + int i = findIndex(resume.uuid); if (i < 0) { - System.out.println("ERROR in method \"update\": " + r.uuid + " not found"); + System.out.println("ERROR in method \"update\": " + resume.uuid + " not found"); return; } - storage[i] = r; + storage[i] = resume; } - void delete(String uuid) { + public void delete(String uuid) { int i = findIndex(uuid); if (i < 0) { System.out.println("ERROR in method \"delete\": " + uuid + " not found"); return; } - for (; i < size; i++) { - storage[i] = storage[i + 1]; - } - if (i > 0) { - storage[size] = null; - size--; - } + storage[i] = storage[size]; + storage[size] = null; + size--; } /** * @return array, contains only Resumes in storage (without null) */ - Resume[] getAll() { + public Resume[] getAll() { return Arrays.copyOf(storage, size); } - int size() { + public int size() { return size; } From c395d5001c2ee8ab108bf9124ebdc437227c74f1 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Wed, 28 Jun 2023 21:00:12 +0300 Subject: [PATCH 38/71] =?UTF-8?q?HW03=20=D0=BD=D0=B5=20=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20Arrays.binarySearch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainArray.java | 14 +++- src/com/learnjava/MainTestArrayStorage.java | 23 +++--- src/com/learnjava/model/Resume.java | 13 +++- .../storage/AbstractArrayStorage.java | 70 +++++++++++++++++ src/com/learnjava/storage/ArrayStorage.java | 78 +++---------------- .../learnjava/storage/SortedArrayStorage.java | 31 ++++++++ src/com/learnjava/storage/Storage.java | 19 +++++ 7 files changed, 165 insertions(+), 83 deletions(-) create mode 100644 src/com/learnjava/storage/AbstractArrayStorage.java create mode 100644 src/com/learnjava/storage/SortedArrayStorage.java create mode 100644 src/com/learnjava/storage/Storage.java diff --git a/src/com/learnjava/MainArray.java b/src/com/learnjava/MainArray.java index 325d8bb..6b85134 100644 --- a/src/com/learnjava/MainArray.java +++ b/src/com/learnjava/MainArray.java @@ -10,13 +10,13 @@ * (just run, no need to understand) */ public class MainArray { - private final static ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + private final static Storage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Resume r; while (true) { - System.out.print("Введите одну из команд - (list | size | save uuid | delete uuid | get uuid | clear | exit): "); + System.out.print("Введите одну из команд - (list | save uuid | delete uuid | get uuid | update uuid | clear | exit): "); String[] params = reader.readLine().trim().toLowerCase().split(" "); if (params.length < 1 || params.length > 2) { System.out.println("Неверная команда."); @@ -35,10 +35,16 @@ public static void main(String[] args) throws IOException { break; case "save": r = new Resume(); - r.uuid = uuid; + r.setUuid(uuid); ARRAY_STORAGE.save(r); printAll(); break; + case "update": + r = new Resume(); + r.setUuid(uuid); + ARRAY_STORAGE.update(r); + printAll(); + break; case "delete": ARRAY_STORAGE.delete(uuid); printAll(); @@ -71,4 +77,4 @@ static void printAll() { } System.out.println("----------------------------"); } -} +} \ No newline at end of file diff --git a/src/com/learnjava/MainTestArrayStorage.java b/src/com/learnjava/MainTestArrayStorage.java index 2d2a2f1..7651e6b 100644 --- a/src/com/learnjava/MainTestArrayStorage.java +++ b/src/com/learnjava/MainTestArrayStorage.java @@ -1,33 +1,34 @@ package com.learnjava; -import com.learnjava.storage.ArrayStorage; -import com.learnjava.model.*; + +import com.learnjava.model.Resume; +import com.learnjava.storage.SortedArrayStorage; + /** * Test for your ArrayStorage implementation */ public class MainTestArrayStorage { - static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + //static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + static final SortedArrayStorage ARRAY_STORAGE = new SortedArrayStorage(); public static void main(String[] args) { Resume r1 = new Resume(); - r1.uuid = "uuid1"; + r1.setUuid("uuid1"); Resume r2 = new Resume(); - r2.uuid = "uuid2"; + r2.setUuid("uuid2"); Resume r3 = new Resume(); - r3.uuid = "uuid3"; + r3.setUuid("uuid3"); ARRAY_STORAGE.save(r1); ARRAY_STORAGE.save(r2); ARRAY_STORAGE.save(r3); - ARRAY_STORAGE.save(r3); - ARRAY_STORAGE.update(r3); - System.out.println("Get r1: " + ARRAY_STORAGE.get(r1.uuid)); + System.out.println("Get r1: " + ARRAY_STORAGE.get(r1.getUuid())); System.out.println("Size: " + ARRAY_STORAGE.size()); System.out.println("Get dummy: " + ARRAY_STORAGE.get("dummy")); printAll(); - ARRAY_STORAGE.delete(r1.uuid); + ARRAY_STORAGE.delete(r1.getUuid()); printAll(); ARRAY_STORAGE.clear(); printAll(); @@ -41,4 +42,4 @@ static void printAll() { System.out.println(r); } } -} +} \ No newline at end of file diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index fa6e782..dc8bb87 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -1,14 +1,23 @@ package com.learnjava.model; + /** * Initial resume class */ public class Resume { // Unique identifier - public String uuid; + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } @Override public String toString() { return uuid; } -} +} \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractArrayStorage.java b/src/com/learnjava/storage/AbstractArrayStorage.java new file mode 100644 index 0000000..79437be --- /dev/null +++ b/src/com/learnjava/storage/AbstractArrayStorage.java @@ -0,0 +1,70 @@ +package com.learnjava.storage; + +import com.learnjava.model.Resume; + +import java.util.Arrays; + +public abstract class AbstractArrayStorage implements Storage { + protected static final int STORAGE_LIMIT = 10000; + protected Resume[] storage = new Resume[STORAGE_LIMIT]; + protected int size = 0; + + public void clear() { + Arrays.fill(storage, 0, size, null); + size = 0; + } + public void update(Resume r) { + int index = getIndex(r.getUuid()); + if (index == -1) { + System.out.println("Resume " + r.getUuid() + " not exist"); + } else { + storage[index] = r; + } + } + + + public void save(Resume r) { + int index = getIndex(r.getUuid()); + if (getIndex(r.getUuid()) != -1) { + System.out.println("Resume " + r.getUuid() + " already exist"); + } else if (size >= STORAGE_LIMIT) { + System.out.println("Storage overflow"); + } else { + putOnIndex(r,index); + size++; + } + } + + public Resume get(String uuid) { + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Resume " + uuid + " not exist"); + return null; + } + return storage[index]; + } + + public void delete(String uuid) { + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Resume " + uuid + " not exist"); + } else { + fillGap(index); + storage[size - 1] = null; + size--; + } + } + + public Resume[] getAll() { + return Arrays.copyOfRange(storage, 0, size); + } + + public int size() { + return size; + } + + protected abstract void putOnIndex(Resume r, int index); + protected abstract void fillGap(int index); + + protected abstract int getIndex(String uuid); +} \ No newline at end of file diff --git a/src/com/learnjava/storage/ArrayStorage.java b/src/com/learnjava/storage/ArrayStorage.java index fde52d9..390e637 100644 --- a/src/com/learnjava/storage/ArrayStorage.java +++ b/src/com/learnjava/storage/ArrayStorage.java @@ -1,82 +1,28 @@ package com.learnjava.storage; - import com.learnjava.model.Resume; - -import java.util.Arrays; - /** * Array based storage for Resumes */ -public class ArrayStorage { - private static final int STORAGE_LIMIT = 10000; - protected final Resume[] storage = new Resume[STORAGE_LIMIT]; - private int size; - - public void clear() { - Arrays.fill(storage, null); - size = 0; - } - - public void save(Resume r) { +public class ArrayStorage extends AbstractArrayStorage { - if (size + 1 > STORAGE_LIMIT) { - System.out.println("ERROR in method \"save\": maximum capacity reached"); - } else { - int i = findIndex(r.uuid); - if (i > 0) { - System.out.println("ERROR in method \"save\": " + r.uuid + " already exists"); - } else { - storage[size++] = r; - } - } - } - - public Resume get(String uuid) { - int i = findIndex(uuid); - if (i < 0) { - System.out.println("ERROR in method \"update\": " + uuid + " not found"); - return null; - } - return storage[i]; + protected void fillGap(int index) { + storage[index] = storage[size - 1]; } - public void update(Resume resume) { - int i = findIndex(resume.uuid); - if (i < 0) { - System.out.println("ERROR in method \"update\": " + resume.uuid + " not found"); - return; - } - storage[i] = resume; + protected void putOnIndex(Resume r, int index) { + storage[size] = r; } - public void delete(String uuid) { - int i = findIndex(uuid); - if (i < 0) { - System.out.println("ERROR in method \"delete\": " + uuid + " not found"); - return; - } - storage[i] = storage[size]; - storage[size] = null; - size--; - } - - /** - * @return array, contains only Resumes in storage (without null) - */ - public Resume[] getAll() { - return Arrays.copyOf(storage, size); - } - - public int size() { - return size; - } - - private int findIndex(String uuid) { + protected int getIndex(String uuid) { for (int i = 0; i < size; i++) { - if (storage[i].uuid.equals(uuid)) { + if (uuid.equals(storage[i].getUuid())) { return i; } } return -1; } -} + + + + +} \ No newline at end of file diff --git a/src/com/learnjava/storage/SortedArrayStorage.java b/src/com/learnjava/storage/SortedArrayStorage.java new file mode 100644 index 0000000..41eb27b --- /dev/null +++ b/src/com/learnjava/storage/SortedArrayStorage.java @@ -0,0 +1,31 @@ +package com.learnjava.storage; +import com.learnjava.model.*; +import java.util.Arrays; + +public class SortedArrayStorage extends AbstractArrayStorage{ + + @Override + protected int getIndex(String uuid) { + Resume searchKey = new Resume(); + searchKey.setUuid(uuid); + return Arrays.binarySearch(storage, 0, size, searchKey); + } + + @Override + protected void fillGap(int index) { + int shiftLeft = size - ( index + 1); + if (shiftLeft > 0) { + System.arraycopy(storage, index + 1, storage, index, shiftLeft); + } + + } + + @Override + protected void putOnIndex(Resume r, int index) { + int insertPos = -index - 1; + int destPos = insertPos + 1; + int length = size - insertPos; + System.arraycopy(storage, insertPos, storage, destPos, length); + storage[insertPos] = r; + } +} \ No newline at end of file diff --git a/src/com/learnjava/storage/Storage.java b/src/com/learnjava/storage/Storage.java new file mode 100644 index 0000000..c087948 --- /dev/null +++ b/src/com/learnjava/storage/Storage.java @@ -0,0 +1,19 @@ +package com.learnjava.storage; +import com.learnjava.model.*; + +public interface Storage { + + void clear(); + + void update(Resume r); + + void save(Resume r); + + Resume get(String uuid); + + void delete(String uuid); + + Resume[] getAll(); + + int size(); +} \ No newline at end of file From 50a94af451894b0b04e7f1f3298c457502d4d429 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Thu, 29 Jun 2023 10:17:09 +0300 Subject: [PATCH 39/71] =?UTF-8?q?HW03=20=D0=B4=D0=BE=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80,=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D0=B4=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/model/Resume.java | 8 +++++++- src/com/learnjava/storage/AbstractArrayStorage.java | 7 +++---- src/com/learnjava/storage/SortedArrayStorage.java | 1 - 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index dc8bb87..aef017f 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -3,7 +3,7 @@ /** * Initial resume class */ -public class Resume { +public class Resume implements Comparable { // Unique identifier private String uuid; @@ -20,4 +20,10 @@ public void setUuid(String uuid) { public String toString() { return uuid; } + + @Override + public int compareTo(Resume otherResume){ + return Integer.compare(getUuid().hashCode(), otherResume.getUuid().hashCode()); + } + } \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractArrayStorage.java b/src/com/learnjava/storage/AbstractArrayStorage.java index 79437be..b087fad 100644 --- a/src/com/learnjava/storage/AbstractArrayStorage.java +++ b/src/com/learnjava/storage/AbstractArrayStorage.java @@ -15,17 +15,16 @@ public void clear() { } public void update(Resume r) { int index = getIndex(r.getUuid()); - if (index == -1) { + if (index < 0) { System.out.println("Resume " + r.getUuid() + " not exist"); } else { storage[index] = r; } } - public void save(Resume r) { int index = getIndex(r.getUuid()); - if (getIndex(r.getUuid()) != -1) { + if (index >= 0) { System.out.println("Resume " + r.getUuid() + " already exist"); } else if (size >= STORAGE_LIMIT) { System.out.println("Storage overflow"); @@ -46,7 +45,7 @@ public Resume get(String uuid) { public void delete(String uuid) { int index = getIndex(uuid); - if (index == -1) { + if (index < 0) { System.out.println("Resume " + uuid + " not exist"); } else { fillGap(index); diff --git a/src/com/learnjava/storage/SortedArrayStorage.java b/src/com/learnjava/storage/SortedArrayStorage.java index 41eb27b..b21c632 100644 --- a/src/com/learnjava/storage/SortedArrayStorage.java +++ b/src/com/learnjava/storage/SortedArrayStorage.java @@ -17,7 +17,6 @@ protected void fillGap(int index) { if (shiftLeft > 0) { System.arraycopy(storage, index + 1, storage, index, shiftLeft); } - } @Override From c699adbfba4b954a994eface47192a334a636f81 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Wed, 5 Jul 2023 20:24:23 +0300 Subject: [PATCH 40/71] =?UTF-8?q?HW04=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B9=D0=B4=D0=B5=D0=BD=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainArray.java | 7 +- src/com/learnjava/MainReflection.java | 22 +++++ src/com/learnjava/MainString.java | 18 ++++ src/com/learnjava/MainTestArrayStorage.java | 14 +-- .../exception/ExistStorageException.java | 7 ++ .../exception/NotExistStorageException.java | 7 ++ .../learnjava/exception/StorageException.java | 14 +++ src/com/learnjava/model/Resume.java | 35 +++++-- .../storage/AbstractArrayStorage.java | 58 ++++++----- src/com/learnjava/storage/ArrayStorage.java | 11 +-- .../learnjava/storage/SortedArrayStorage.java | 33 +++---- .../storage/AbstractArrayStorageTest.java | 98 +++++++++++++++++++ .../learnjava/storage/ArrayStorageTest.java | 12 +++ .../storage/SortedArrayStorageTest.java | 11 +++ 14 files changed, 281 insertions(+), 66 deletions(-) create mode 100644 src/com/learnjava/MainReflection.java create mode 100644 src/com/learnjava/MainString.java create mode 100644 src/com/learnjava/exception/ExistStorageException.java create mode 100644 src/com/learnjava/exception/NotExistStorageException.java create mode 100644 src/com/learnjava/exception/StorageException.java create mode 100644 test/com/learnjava/storage/AbstractArrayStorageTest.java create mode 100644 test/com/learnjava/storage/ArrayStorageTest.java create mode 100644 test/com/learnjava/storage/SortedArrayStorageTest.java diff --git a/src/com/learnjava/MainArray.java b/src/com/learnjava/MainArray.java index 6b85134..25d7675 100644 --- a/src/com/learnjava/MainArray.java +++ b/src/com/learnjava/MainArray.java @@ -1,6 +1,7 @@ package com.learnjava; import com.learnjava.model.*; import com.learnjava.storage.*; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -34,14 +35,12 @@ public static void main(String[] args) throws IOException { System.out.println(ARRAY_STORAGE.size()); break; case "save": - r = new Resume(); - r.setUuid(uuid); + r = new Resume(uuid); ARRAY_STORAGE.save(r); printAll(); break; case "update": - r = new Resume(); - r.setUuid(uuid); + r = new Resume(uuid); ARRAY_STORAGE.update(r); printAll(); break; diff --git a/src/com/learnjava/MainReflection.java b/src/com/learnjava/MainReflection.java new file mode 100644 index 0000000..b0dc7a1 --- /dev/null +++ b/src/com/learnjava/MainReflection.java @@ -0,0 +1,22 @@ +package com.learnjava; + +import com.learnjava.model.Resume; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class MainReflection { + + public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + Resume r = new Resume(); + Field field = r.getClass().getDeclaredFields()[0]; + field.setAccessible(true); + System.out.println(field.getName()); + System.out.println(field.get(r)); + field.set(r, "new_uuid"); + Method method = r.getClass().getMethod("toString"); + Object result = method.invoke(r); + System.out.println(r); + } +} \ No newline at end of file diff --git a/src/com/learnjava/MainString.java b/src/com/learnjava/MainString.java new file mode 100644 index 0000000..4c0b65a --- /dev/null +++ b/src/com/learnjava/MainString.java @@ -0,0 +1,18 @@ +package com.learnjava; + +public class MainString { + public static void main(String[] args) { + String[] strArray = new String[]{"1", "2", "3", "4", "5"}; +// String result = ""; + StringBuilder sb = new StringBuilder(); + for (String str : strArray) { + sb.append(str).append(", "); + } + System.out.println(sb.toString()); + + String str1 = "abc"; + String str3 = "c"; + String str2 = ("ab" + str3).intern(); + System.out.println(str1 == str2); + } +} \ No newline at end of file diff --git a/src/com/learnjava/MainTestArrayStorage.java b/src/com/learnjava/MainTestArrayStorage.java index 7651e6b..00c85b9 100644 --- a/src/com/learnjava/MainTestArrayStorage.java +++ b/src/com/learnjava/MainTestArrayStorage.java @@ -1,22 +1,18 @@ package com.learnjava; import com.learnjava.model.Resume; -import com.learnjava.storage.SortedArrayStorage; +import com.learnjava.storage.*; /** * Test for your ArrayStorage implementation */ public class MainTestArrayStorage { - //static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); - static final SortedArrayStorage ARRAY_STORAGE = new SortedArrayStorage(); + static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { - Resume r1 = new Resume(); - r1.setUuid("uuid1"); - Resume r2 = new Resume(); - r2.setUuid("uuid2"); - Resume r3 = new Resume(); - r3.setUuid("uuid3"); + Resume r1 = new Resume("uuid1"); + Resume r2 = new Resume("uuid2"); + Resume r3 = new Resume("uuid3"); ARRAY_STORAGE.save(r1); ARRAY_STORAGE.save(r2); diff --git a/src/com/learnjava/exception/ExistStorageException.java b/src/com/learnjava/exception/ExistStorageException.java new file mode 100644 index 0000000..fc0b090 --- /dev/null +++ b/src/com/learnjava/exception/ExistStorageException.java @@ -0,0 +1,7 @@ +package com.learnjava.exception; + +public class ExistStorageException extends StorageException { + public ExistStorageException(String uuid) { + super("Resume " + uuid + " already exist", uuid); + } +} \ No newline at end of file diff --git a/src/com/learnjava/exception/NotExistStorageException.java b/src/com/learnjava/exception/NotExistStorageException.java new file mode 100644 index 0000000..6429e6a --- /dev/null +++ b/src/com/learnjava/exception/NotExistStorageException.java @@ -0,0 +1,7 @@ +package com.learnjava.exception; + +public class NotExistStorageException extends StorageException { + public NotExistStorageException(String uuid) { + super("Resume " + uuid + " not exist", uuid); + } +} \ No newline at end of file diff --git a/src/com/learnjava/exception/StorageException.java b/src/com/learnjava/exception/StorageException.java new file mode 100644 index 0000000..f058bbf --- /dev/null +++ b/src/com/learnjava/exception/StorageException.java @@ -0,0 +1,14 @@ +package com.learnjava.exception; + +public class StorageException extends RuntimeException { + private final String uuid; + + public StorageException(String message, String uuid) { + super(message); + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index aef017f..01c6680 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -1,19 +1,41 @@ package com.learnjava.model; + +import java.util.UUID; + /** - * Initial resume class + * ru.javawebinar.basejava.model.Resume class */ public class Resume implements Comparable { // Unique identifier - private String uuid; + private final String uuid; + + public Resume() { + this(UUID.randomUUID().toString()); + } + + public Resume(String uuid) { + this.uuid = uuid; + } public String getUuid() { return uuid; } - public void setUuid(String uuid) { - this.uuid = uuid; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Resume resume = (Resume) o; + + return uuid.equals(resume.uuid); + } + + @Override + public int hashCode() { + return uuid.hashCode(); } @Override @@ -22,8 +44,7 @@ public String toString() { } @Override - public int compareTo(Resume otherResume){ - return Integer.compare(getUuid().hashCode(), otherResume.getUuid().hashCode()); + public int compareTo(Resume o) { + return uuid.compareTo(o.uuid); } - } \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractArrayStorage.java b/src/com/learnjava/storage/AbstractArrayStorage.java index b087fad..9bef858 100644 --- a/src/com/learnjava/storage/AbstractArrayStorage.java +++ b/src/com/learnjava/storage/AbstractArrayStorage.java @@ -1,69 +1,81 @@ package com.learnjava.storage; +import com.learnjava.exception.ExistStorageException; +import com.learnjava.exception.NotExistStorageException; +import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; import java.util.Arrays; + +/** + * Array based storage for Resumes + */ public abstract class AbstractArrayStorage implements Storage { protected static final int STORAGE_LIMIT = 10000; + protected Resume[] storage = new Resume[STORAGE_LIMIT]; protected int size = 0; + public int size() { + return size; + } + public void clear() { Arrays.fill(storage, 0, size, null); size = 0; } + public void update(Resume r) { int index = getIndex(r.getUuid()); if (index < 0) { - System.out.println("Resume " + r.getUuid() + " not exist"); + throw new NotExistStorageException(r.getUuid()); } else { storage[index] = r; } } + /** + * @return array, contains only Resumes in storage (without null) + */ + public Resume[] getAll() { + return Arrays.copyOfRange(storage, 0, size); + } + public void save(Resume r) { int index = getIndex(r.getUuid()); if (index >= 0) { - System.out.println("Resume " + r.getUuid() + " already exist"); - } else if (size >= STORAGE_LIMIT) { - System.out.println("Storage overflow"); + throw new ExistStorageException(r.getUuid()); + } else if (size == STORAGE_LIMIT) { + throw new StorageException("Storage overflow", r.getUuid()); } else { - putOnIndex(r,index); + insertElement(r, index); size++; } } - public Resume get(String uuid) { - int index = getIndex(uuid); - if (index == -1) { - System.out.println("Resume " + uuid + " not exist"); - return null; - } - return storage[index]; - } - public void delete(String uuid) { int index = getIndex(uuid); if (index < 0) { - System.out.println("Resume " + uuid + " not exist"); + throw new NotExistStorageException(uuid); } else { - fillGap(index); + fillDeletedElement(index); storage[size - 1] = null; size--; } } - public Resume[] getAll() { - return Arrays.copyOfRange(storage, 0, size); + public Resume get(String uuid) { + int index = getIndex(uuid); + if (index < 0) { + throw new NotExistStorageException(uuid); + } + return storage[index]; } - public int size() { - return size; - } + protected abstract void fillDeletedElement(int index); - protected abstract void putOnIndex(Resume r, int index); - protected abstract void fillGap(int index); + protected abstract void insertElement(Resume r, int index); protected abstract int getIndex(String uuid); } \ No newline at end of file diff --git a/src/com/learnjava/storage/ArrayStorage.java b/src/com/learnjava/storage/ArrayStorage.java index 390e637..0da3539 100644 --- a/src/com/learnjava/storage/ArrayStorage.java +++ b/src/com/learnjava/storage/ArrayStorage.java @@ -5,14 +5,17 @@ */ public class ArrayStorage extends AbstractArrayStorage { - protected void fillGap(int index) { + @Override + protected void fillDeletedElement(int index) { storage[index] = storage[size - 1]; } - protected void putOnIndex(Resume r, int index) { + @Override + protected void insertElement(Resume r, int index) { storage[size] = r; } + @Override protected int getIndex(String uuid) { for (int i = 0; i < size; i++) { if (uuid.equals(storage[i].getUuid())) { @@ -21,8 +24,4 @@ protected int getIndex(String uuid) { } return -1; } - - - - } \ No newline at end of file diff --git a/src/com/learnjava/storage/SortedArrayStorage.java b/src/com/learnjava/storage/SortedArrayStorage.java index b21c632..5dcf093 100644 --- a/src/com/learnjava/storage/SortedArrayStorage.java +++ b/src/com/learnjava/storage/SortedArrayStorage.java @@ -1,30 +1,29 @@ package com.learnjava.storage; import com.learnjava.model.*; -import java.util.Arrays; +import java.util.Arrays; -public class SortedArrayStorage extends AbstractArrayStorage{ + +public class SortedArrayStorage extends AbstractArrayStorage { @Override - protected int getIndex(String uuid) { - Resume searchKey = new Resume(); - searchKey.setUuid(uuid); - return Arrays.binarySearch(storage, 0, size, searchKey); + protected void fillDeletedElement(int index) { + int numMoved = size - index - 1; + if (numMoved > 0) { + System.arraycopy(storage, index + 1, storage, index, numMoved); + } } @Override - protected void fillGap(int index) { - int shiftLeft = size - ( index + 1); - if (shiftLeft > 0) { - System.arraycopy(storage, index + 1, storage, index, shiftLeft); - } + protected void insertElement(Resume r, int index) { +// http://codereview.stackexchange.com/questions/36221/binary-search-for-inserting-in-array#answer-36239 + int insertIdx = -index - 1; + System.arraycopy(storage, insertIdx, storage, insertIdx + 1, size - insertIdx); + storage[insertIdx] = r; } @Override - protected void putOnIndex(Resume r, int index) { - int insertPos = -index - 1; - int destPos = insertPos + 1; - int length = size - insertPos; - System.arraycopy(storage, insertPos, storage, destPos, length); - storage[insertPos] = r; + protected int getIndex(String uuid) { + Resume searchKey = new Resume(uuid); + return Arrays.binarySearch(storage, 0, size, searchKey); } } \ No newline at end of file diff --git a/test/com/learnjava/storage/AbstractArrayStorageTest.java b/test/com/learnjava/storage/AbstractArrayStorageTest.java new file mode 100644 index 0000000..2139cd9 --- /dev/null +++ b/test/com/learnjava/storage/AbstractArrayStorageTest.java @@ -0,0 +1,98 @@ +package com.learnjava.storage; + +import com.learnjava.exception.NotExistStorageException; +import com.learnjava.exception.StorageException; +import com.learnjava.model.Resume; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + + +class AbstractArrayStorageTest { + private Storage storage; + + private static final Resume TEST_RESUME1 = new Resume("uuid1"); + private static final Resume TEST_RESUME2 = new Resume("uuid2"); + private static final Resume TEST_RESUME3 = new Resume("extra_uuid"); + + protected void initArrayStorage() { + this.storage = new ArrayStorage(); + } + protected void initSortedStorage() { + this.storage = new SortedArrayStorage(); + } + + @BeforeEach + public void beforeEach() { + if (storage != null){ + storage.clear(); + storage.save(TEST_RESUME1); + storage.save(TEST_RESUME2); + } + } + + @Test + void size() { + Assertions.assertEquals(2, storage.size()); + } + + @Test + void clear() { + storage.clear(); + Assertions.assertEquals(0, storage.size()); + } + + @Test + void update() { + Assertions.assertThrows(NotExistStorageException.class, () -> { + storage.get("not existing uuid"); + }); + } + + @Test + void getAll() { + Resume[] wholeStorage = storage.getAll(); + Assertions.assertEquals(2, wholeStorage.length); + } + + @Test + void save() { + storage.save(TEST_RESUME3); + Assertions.assertEquals(3, storage.size()); + } + + @Test + public void overflow() { + Assertions.assertThrows(StorageException.class, () -> { + + for (int i = storage.size() + 1; i <= AbstractArrayStorage.STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } + storage.save(new Resume()); + }); + } + + @Test + void delete() { + Assertions.assertThrows(NotExistStorageException.class, () -> { + storage.delete("uuid1"); + Assertions.assertEquals(1, storage.size()); + storage.get("uuid1"); + }); + } + + @Test + void get() { + Assertions.assertEquals(TEST_RESUME1, storage.get(TEST_RESUME1.getUuid())); + Assertions.assertEquals(TEST_RESUME2, storage.get(TEST_RESUME2.getUuid())); + } + + /* @Test + public void getNotExist() { + Assertions.assertThrows(NotExistStorageException.class, () -> { + storage.get("NON_EXISTING_UUID"); + }); + } + + */ +} \ No newline at end of file diff --git a/test/com/learnjava/storage/ArrayStorageTest.java b/test/com/learnjava/storage/ArrayStorageTest.java new file mode 100644 index 0000000..0092fc5 --- /dev/null +++ b/test/com/learnjava/storage/ArrayStorageTest.java @@ -0,0 +1,12 @@ +package com.learnjava.storage; + +public class ArrayStorageTest extends AbstractArrayStorageTest { + + public ArrayStorageTest() { + // если передавать ссылку на потомка в конструктор супера, происходит эксепшн + // https://stackoverflow.com/questions/67645739/no-parameterresolver-registered-for-parameter-xxxx-in-constructor-junit5-java + + super.initArrayStorage(); + } + +} \ No newline at end of file diff --git a/test/com/learnjava/storage/SortedArrayStorageTest.java b/test/com/learnjava/storage/SortedArrayStorageTest.java new file mode 100644 index 0000000..68867e1 --- /dev/null +++ b/test/com/learnjava/storage/SortedArrayStorageTest.java @@ -0,0 +1,11 @@ +package com.learnjava.storage; + +public class SortedArrayStorageTest extends AbstractArrayStorageTest { + + public SortedArrayStorageTest() { + // если передавать ссылку на потомка в конструктор супера, происходит эксепшн + // https://stackoverflow.com/questions/67645739/no-parameterresolver-registered-for-parameter-xxxx-in-constructor-junit5-java + super.initSortedStorage(); + } + +} \ No newline at end of file From e6e57a2fac5538c1d12dada3088c0eddfee88df5 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Thu, 20 Jul 2023 13:00:51 +0300 Subject: [PATCH 41/71] =?UTF-8?q?HW04=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B9=D0=B4=D0=B5=D0=BD=D1=8B,=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=83=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storage/AbstractArrayStorageTest.java | 104 ++++++++++++------ .../learnjava/storage/ArrayStorageTest.java | 5 +- .../storage/SortedArrayStorageTest.java | 5 +- 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/test/com/learnjava/storage/AbstractArrayStorageTest.java b/test/com/learnjava/storage/AbstractArrayStorageTest.java index 2139cd9..54977e3 100644 --- a/test/com/learnjava/storage/AbstractArrayStorageTest.java +++ b/test/com/learnjava/storage/AbstractArrayStorageTest.java @@ -9,90 +9,124 @@ class AbstractArrayStorageTest { - private Storage storage; + protected Storage storage; + protected Storage emptyStorage; + private static final String UUID_1 = "uuid1"; + private static final Resume RESUME_1 = new Resume(UUID_1); - private static final Resume TEST_RESUME1 = new Resume("uuid1"); - private static final Resume TEST_RESUME2 = new Resume("uuid2"); - private static final Resume TEST_RESUME3 = new Resume("extra_uuid"); + private static final String UUID_2 = "uuid2"; + private static final Resume RESUME_2 = new Resume(UUID_2); + + private static final String UUID_3 = "uuid3"; + private static final Resume RESUME_3 = new Resume(UUID_3); + + private static final String UUID_4 = "extra_uuid"; + private static final Resume RESUME_4 = new Resume(UUID_4); + + private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; + private static final Resume RESUME_5 = new Resume(UUID_NOT_EXIST); - protected void initArrayStorage() { - this.storage = new ArrayStorage(); - } - protected void initSortedStorage() { - this.storage = new SortedArrayStorage(); - } @BeforeEach public void beforeEach() { - if (storage != null){ + if (storage != null) { storage.clear(); - storage.save(TEST_RESUME1); - storage.save(TEST_RESUME2); + storage.save(RESUME_1); + storage.save(RESUME_2); + storage.save(RESUME_3); } } + private void assertGet(Resume r) { + Assertions.assertEquals(r, storage.get(r.getUuid())); + } + + private void assertSize(int size) { + Assertions.assertEquals(size, storage.size()); + } + + @Test void size() { - Assertions.assertEquals(2, storage.size()); + assertSize(3); } @Test void clear() { storage.clear(); - Assertions.assertEquals(0, storage.size()); + assertSize(0); + Assertions.assertArrayEquals(storage.getAll(), emptyStorage.getAll()); } @Test void update() { - Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.get("not existing uuid"); - }); + Resume newResume = new Resume(UUID_1); + storage.update(newResume); + Assertions.assertSame(newResume, storage.get(UUID_1)); } @Test void getAll() { - Resume[] wholeStorage = storage.getAll(); - Assertions.assertEquals(2, wholeStorage.length); + Resume[] array = storage.getAll(); + Assertions.assertEquals(3, array.length); + Assertions.assertEquals(RESUME_1, array[0]); + Assertions.assertEquals(RESUME_2, array[1]); + Assertions.assertEquals(RESUME_3, array[2]); } @Test void save() { - storage.save(TEST_RESUME3); - Assertions.assertEquals(3, storage.size()); + storage.save(RESUME_4); + assertSize(4); + assertGet(RESUME_4); } @Test public void overflow() { + storage.clear(); + for (int i = 0; i < AbstractArrayStorage.STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } Assertions.assertThrows(StorageException.class, () -> { - - for (int i = storage.size() + 1; i <= AbstractArrayStorage.STORAGE_LIMIT; i++) { - storage.save(new Resume()); - } storage.save(new Resume()); }); } @Test void delete() { + storage.delete(UUID_1); Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.delete("uuid1"); - Assertions.assertEquals(1, storage.size()); - storage.get("uuid1"); + assertSize(2); + storage.get(UUID_1); }); } @Test void get() { - Assertions.assertEquals(TEST_RESUME1, storage.get(TEST_RESUME1.getUuid())); - Assertions.assertEquals(TEST_RESUME2, storage.get(TEST_RESUME2.getUuid())); + + assertGet(RESUME_1); + assertGet(RESUME_2); + assertGet(RESUME_3); } - /* @Test - public void getNotExist() { + @Test + void getNotExist() { Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.get("NON_EXISTING_UUID"); + storage.get(UUID_NOT_EXIST); }); } - */ + @Test + void deleteNotExist() { + Assertions.assertThrows(NotExistStorageException.class, () -> { + storage.delete(UUID_NOT_EXIST); + }); + } + + @Test + public void updateNotExist() { + Assertions.assertThrows(NotExistStorageException.class, () -> { + storage.update(RESUME_5); + }); + } } \ No newline at end of file diff --git a/test/com/learnjava/storage/ArrayStorageTest.java b/test/com/learnjava/storage/ArrayStorageTest.java index 0092fc5..edeaa17 100644 --- a/test/com/learnjava/storage/ArrayStorageTest.java +++ b/test/com/learnjava/storage/ArrayStorageTest.java @@ -3,10 +3,9 @@ public class ArrayStorageTest extends AbstractArrayStorageTest { public ArrayStorageTest() { - // если передавать ссылку на потомка в конструктор супера, происходит эксепшн - // https://stackoverflow.com/questions/67645739/no-parameterresolver-registered-for-parameter-xxxx-in-constructor-junit5-java - super.initArrayStorage(); + super.storage = new ArrayStorage(); + super.emptyStorage = new ArrayStorage(); } } \ No newline at end of file diff --git a/test/com/learnjava/storage/SortedArrayStorageTest.java b/test/com/learnjava/storage/SortedArrayStorageTest.java index 68867e1..4f0fe06 100644 --- a/test/com/learnjava/storage/SortedArrayStorageTest.java +++ b/test/com/learnjava/storage/SortedArrayStorageTest.java @@ -3,9 +3,8 @@ public class SortedArrayStorageTest extends AbstractArrayStorageTest { public SortedArrayStorageTest() { - // если передавать ссылку на потомка в конструктор супера, происходит эксепшн - // https://stackoverflow.com/questions/67645739/no-parameterresolver-registered-for-parameter-xxxx-in-constructor-junit5-java - super.initSortedStorage(); + super.storage = new SortedArrayStorage(); + super.emptyStorage = new SortedArrayStorage(); } } \ No newline at end of file From cf808d9e271cc9c0d235cdd5f496ea2fc8df0250 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Fri, 21 Jul 2023 19:32:40 +0300 Subject: [PATCH 42/71] =?UTF-8?q?HW04=20delete=20=D0=BF=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/com/learnjava/storage/AbstractArrayStorageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/com/learnjava/storage/AbstractArrayStorageTest.java b/test/com/learnjava/storage/AbstractArrayStorageTest.java index 54977e3..9a0f2e8 100644 --- a/test/com/learnjava/storage/AbstractArrayStorageTest.java +++ b/test/com/learnjava/storage/AbstractArrayStorageTest.java @@ -95,8 +95,8 @@ public void overflow() { @Test void delete() { storage.delete(UUID_1); + assertSize(2); Assertions.assertThrows(NotExistStorageException.class, () -> { - assertSize(2); storage.get(UUID_1); }); } From f41c5aacde5544af2b3479dbfff1c518367fb65c Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Fri, 21 Jul 2023 20:53:01 +0300 Subject: [PATCH 43/71] =?UTF-8?q?HW05=20=D1=81=D1=85=D0=B5=D0=BC=D0=B0=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D0=B9=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?,=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BD=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D1=8B=20=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D0=B4=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainReflection.java | 22 ------- .../storage/AbstractArrayStorage.java | 59 ++++++++---------- .../learnjava/storage/AbstractStorage.java | 54 ++++++++++++++++ src/com/learnjava/storage/ArrayStorage.java | 4 +- src/com/learnjava/storage/ListStorage.java | 61 +++++++++++++++++++ .../learnjava/storage/SortedArrayStorage.java | 2 +- ...rageTest.java => AbstractStorageTest.java} | 28 +++++---- .../learnjava/storage/ArrayStorageTest.java | 7 +-- .../learnjava/storage/ListStorageTest.java | 9 +++ .../storage/SortedArrayStorageTest.java | 6 +- 10 files changed, 174 insertions(+), 78 deletions(-) delete mode 100644 src/com/learnjava/MainReflection.java create mode 100644 src/com/learnjava/storage/AbstractStorage.java create mode 100644 src/com/learnjava/storage/ListStorage.java rename test/com/learnjava/storage/{AbstractArrayStorageTest.java => AbstractStorageTest.java} (83%) create mode 100644 test/com/learnjava/storage/ListStorageTest.java diff --git a/src/com/learnjava/MainReflection.java b/src/com/learnjava/MainReflection.java deleted file mode 100644 index b0dc7a1..0000000 --- a/src/com/learnjava/MainReflection.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.learnjava; - -import com.learnjava.model.Resume; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class MainReflection { - - public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { - Resume r = new Resume(); - Field field = r.getClass().getDeclaredFields()[0]; - field.setAccessible(true); - System.out.println(field.getName()); - System.out.println(field.get(r)); - field.set(r, "new_uuid"); - Method method = r.getClass().getMethod("toString"); - Object result = method.invoke(r); - System.out.println(r); - } -} \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractArrayStorage.java b/src/com/learnjava/storage/AbstractArrayStorage.java index 9bef858..47cc48b 100644 --- a/src/com/learnjava/storage/AbstractArrayStorage.java +++ b/src/com/learnjava/storage/AbstractArrayStorage.java @@ -1,7 +1,5 @@ package com.learnjava.storage; -import com.learnjava.exception.ExistStorageException; -import com.learnjava.exception.NotExistStorageException; import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; @@ -11,7 +9,7 @@ /** * Array based storage for Resumes */ -public abstract class AbstractArrayStorage implements Storage { +public abstract class AbstractArrayStorage extends AbstractStorage { protected static final int STORAGE_LIMIT = 10000; protected Resume[] storage = new Resume[STORAGE_LIMIT]; @@ -26,56 +24,47 @@ public void clear() { size = 0; } - public void update(Resume r) { - int index = getIndex(r.getUuid()); - if (index < 0) { - throw new NotExistStorageException(r.getUuid()); - } else { - storage[index] = r; - } + @Override + protected void Update(Resume r, Object index) { + storage[(Integer) index] = r; } - /** - * @return array, contains only Resumes in storage (without null) - */ + public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } - public void save(Resume r) { - int index = getIndex(r.getUuid()); - if (index >= 0) { - throw new ExistStorageException(r.getUuid()); - } else if (size == STORAGE_LIMIT) { + @Override + protected void Save(Resume r, Object index) { + if (size == STORAGE_LIMIT) { throw new StorageException("Storage overflow", r.getUuid()); } else { - insertElement(r, index); + insertElement(r, (Integer) index); size++; } } - public void delete(String uuid) { - int index = getIndex(uuid); - if (index < 0) { - throw new NotExistStorageException(uuid); - } else { - fillDeletedElement(index); - storage[size - 1] = null; - size--; - } + @Override + public void Delete(Object index) { + fillDeletedElement((Integer) index); + storage[size - 1] = null; + size--; } - public Resume get(String uuid) { - int index = getIndex(uuid); - if (index < 0) { - throw new NotExistStorageException(uuid); - } - return storage[index]; + public Resume getResume(Object index) { + return storage[(Integer) index]; } + + @Override + protected boolean Exist(Object index) { + return (Integer) index >= 0; + } + + protected abstract void fillDeletedElement(int index); protected abstract void insertElement(Resume r, int index); - protected abstract int getIndex(String uuid); + protected abstract Integer getSearchKey(String uuid); } \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractStorage.java b/src/com/learnjava/storage/AbstractStorage.java new file mode 100644 index 0000000..389f5c3 --- /dev/null +++ b/src/com/learnjava/storage/AbstractStorage.java @@ -0,0 +1,54 @@ +package com.learnjava.storage; +import com.learnjava.exception.ExistStorageException; +import com.learnjava.exception.NotExistStorageException; +import com.learnjava.model.Resume; + +public abstract class AbstractStorage implements Storage { + protected abstract Object getSearchKey(String uuid); + + protected abstract void Update(Resume r, Object searchKey); + + protected abstract boolean Exist(Object searchKey); + + protected abstract void Save(Resume r, Object searchKey); + + protected abstract Resume getResume(Object searchKey); + + protected abstract void Delete(Object searchKey); + + public void update(Resume r) { + Object searchKey = getExistedSearchKey(r.getUuid()); + Update(r, searchKey); + } + + public void save(Resume r) { + Object searchKey = getNotExistedSearchKey(r.getUuid()); + Save(r, searchKey); + } + + public void delete(String uuid) { + Object searchKey = getExistedSearchKey(uuid); + Delete(searchKey); + } + + public Resume get(String uuid) { + Object searchKey = getExistedSearchKey(uuid); + return getResume(searchKey); + } + + private Object getExistedSearchKey(String uuid) { + Object searchKey = getSearchKey(uuid); + if (!Exist(searchKey)) { + throw new NotExistStorageException(uuid); + } + return searchKey; + } + + private Object getNotExistedSearchKey(String uuid) { + Object searchKey = getSearchKey(uuid); + if (Exist(searchKey)) { + throw new ExistStorageException(uuid); + } + return searchKey; + } +} diff --git a/src/com/learnjava/storage/ArrayStorage.java b/src/com/learnjava/storage/ArrayStorage.java index 0da3539..324c854 100644 --- a/src/com/learnjava/storage/ArrayStorage.java +++ b/src/com/learnjava/storage/ArrayStorage.java @@ -15,8 +15,7 @@ protected void insertElement(Resume r, int index) { storage[size] = r; } - @Override - protected int getIndex(String uuid) { + protected Integer getSearchKey(String uuid) { for (int i = 0; i < size; i++) { if (uuid.equals(storage[i].getUuid())) { return i; @@ -24,4 +23,5 @@ protected int getIndex(String uuid) { } return -1; } + } \ No newline at end of file diff --git a/src/com/learnjava/storage/ListStorage.java b/src/com/learnjava/storage/ListStorage.java new file mode 100644 index 0000000..b2dfe49 --- /dev/null +++ b/src/com/learnjava/storage/ListStorage.java @@ -0,0 +1,61 @@ +package com.learnjava.storage; + +import com.learnjava.model.Resume; + +import java.util.ArrayList; +import java.util.List; + +public class ListStorage extends AbstractStorage { + protected List list = new ArrayList<>(); + + @Override + protected Integer getSearchKey(String uuid) { + for (int i = 0; i < list.size(); i++) { + if (list.get(i).getUuid().equals(uuid)) { + return i; + } + } + return null; + } + + @Override + protected boolean Exist(Object searchKey) { + return searchKey != null; + } + + @Override + protected void Update(Resume r, Object searchKey) { + list.set((Integer) searchKey, r); + } + + @Override + protected void Save(Resume r, Object searchKey) { + list.add(r); + } + + @Override + protected Resume getResume(Object searchKey) { + return list.get((Integer) searchKey); + } + + @Override + protected void Delete(Object searchKey) { + list.remove(((Integer) searchKey).intValue()); + } + + @Override + public void clear() { + list.clear(); + } + + @Override + public Resume[] getAll() { + return list.toArray(new Resume[list.size()]); + } + + @Override + public int size() { + return list.size(); + } + +} diff --git a/src/com/learnjava/storage/SortedArrayStorage.java b/src/com/learnjava/storage/SortedArrayStorage.java index 5dcf093..8ab7a1c 100644 --- a/src/com/learnjava/storage/SortedArrayStorage.java +++ b/src/com/learnjava/storage/SortedArrayStorage.java @@ -22,7 +22,7 @@ protected void insertElement(Resume r, int index) { } @Override - protected int getIndex(String uuid) { + protected Integer getSearchKey(String uuid) { Resume searchKey = new Resume(uuid); return Arrays.binarySearch(storage, 0, size, searchKey); } diff --git a/test/com/learnjava/storage/AbstractArrayStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java similarity index 83% rename from test/com/learnjava/storage/AbstractArrayStorageTest.java rename to test/com/learnjava/storage/AbstractStorageTest.java index 9a0f2e8..4c000ad 100644 --- a/test/com/learnjava/storage/AbstractArrayStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -1,5 +1,4 @@ package com.learnjava.storage; - import com.learnjava.exception.NotExistStorageException; import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; @@ -7,10 +6,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - -class AbstractArrayStorageTest { +public abstract class AbstractStorageTest { protected Storage storage; protected Storage emptyStorage; + protected boolean overflowApplicable; private static final String UUID_1 = "uuid1"; private static final Resume RESUME_1 = new Resume(UUID_1); @@ -26,6 +25,11 @@ class AbstractArrayStorageTest { private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; private static final Resume RESUME_5 = new Resume(UUID_NOT_EXIST); + protected AbstractStorageTest(Storage storage, Storage emptyStorage) { + this.storage = storage; + this.emptyStorage = emptyStorage; + } + @BeforeEach public void beforeEach() { @@ -82,14 +86,16 @@ void save() { } @Test - public void overflow() { - storage.clear(); - for (int i = 0; i < AbstractArrayStorage.STORAGE_LIMIT; i++) { - storage.save(new Resume()); + void overflow() { + if (overflowApplicable) { + storage.clear(); + for (int i = 0; i < AbstractArrayStorage.STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } + Assertions.assertThrows(StorageException.class, () -> { + storage.save(new Resume()); + }); } - Assertions.assertThrows(StorageException.class, () -> { - storage.save(new Resume()); - }); } @Test @@ -129,4 +135,4 @@ public void updateNotExist() { storage.update(RESUME_5); }); } -} \ No newline at end of file +} diff --git a/test/com/learnjava/storage/ArrayStorageTest.java b/test/com/learnjava/storage/ArrayStorageTest.java index edeaa17..92b7d38 100644 --- a/test/com/learnjava/storage/ArrayStorageTest.java +++ b/test/com/learnjava/storage/ArrayStorageTest.java @@ -1,11 +1,10 @@ package com.learnjava.storage; -public class ArrayStorageTest extends AbstractArrayStorageTest { +public class ArrayStorageTest extends AbstractStorageTest { public ArrayStorageTest() { - - super.storage = new ArrayStorage(); - super.emptyStorage = new ArrayStorage(); + super(new ArrayStorage(), new ArrayStorage()); + super.overflowApplicable = true; } } \ No newline at end of file diff --git a/test/com/learnjava/storage/ListStorageTest.java b/test/com/learnjava/storage/ListStorageTest.java new file mode 100644 index 0000000..370bc0a --- /dev/null +++ b/test/com/learnjava/storage/ListStorageTest.java @@ -0,0 +1,9 @@ +package com.learnjava.storage; + +public class ListStorageTest extends AbstractStorageTest { + public ListStorageTest() { + super(new ListStorage(), new ListStorage() ); + super.overflowApplicable = false; + } + +} \ No newline at end of file diff --git a/test/com/learnjava/storage/SortedArrayStorageTest.java b/test/com/learnjava/storage/SortedArrayStorageTest.java index 4f0fe06..613b80e 100644 --- a/test/com/learnjava/storage/SortedArrayStorageTest.java +++ b/test/com/learnjava/storage/SortedArrayStorageTest.java @@ -1,10 +1,10 @@ package com.learnjava.storage; -public class SortedArrayStorageTest extends AbstractArrayStorageTest { +public class SortedArrayStorageTest extends AbstractStorageTest { public SortedArrayStorageTest() { - super.storage = new SortedArrayStorage(); - super.emptyStorage = new SortedArrayStorage(); + super(new SortedArrayStorage(), new SortedArrayStorage()); + super.overflowApplicable = true; } } \ No newline at end of file From 93d50f7e3159fbfed8e861fec82d643fb2f52294 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Sun, 23 Jul 2023 11:35:33 +0300 Subject: [PATCH 44/71] =?UTF-8?q?HW05=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D1=8B,=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20MapStorage?= =?UTF-8?q?=20=D0=B8=20MapStorageTest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storage/AbstractArrayStorage.java | 10 ++-- .../learnjava/storage/AbstractStorage.java | 22 +++---- src/com/learnjava/storage/ListStorage.java | 12 ++-- src/com/learnjava/storage/MapStorage.java | 59 +++++++++++++++++++ .../storage/AbstractStorageTest.java | 2 +- .../com/learnjava/storage/MapStorageTest.java | 8 +++ 6 files changed, 90 insertions(+), 23 deletions(-) create mode 100644 src/com/learnjava/storage/MapStorage.java create mode 100644 test/com/learnjava/storage/MapStorageTest.java diff --git a/src/com/learnjava/storage/AbstractArrayStorage.java b/src/com/learnjava/storage/AbstractArrayStorage.java index 47cc48b..96e4956 100644 --- a/src/com/learnjava/storage/AbstractArrayStorage.java +++ b/src/com/learnjava/storage/AbstractArrayStorage.java @@ -25,7 +25,7 @@ public void clear() { } @Override - protected void Update(Resume r, Object index) { + protected void doUpdate(Resume r, Object index) { storage[(Integer) index] = r; } @@ -35,7 +35,7 @@ public Resume[] getAll() { } @Override - protected void Save(Resume r, Object index) { + protected void doSave(Resume r, Object index) { if (size == STORAGE_LIMIT) { throw new StorageException("Storage overflow", r.getUuid()); } else { @@ -45,19 +45,19 @@ protected void Save(Resume r, Object index) { } @Override - public void Delete(Object index) { + public void doDelete(Object index) { fillDeletedElement((Integer) index); storage[size - 1] = null; size--; } - public Resume getResume(Object index) { + public Resume doGet(Object index) { return storage[(Integer) index]; } @Override - protected boolean Exist(Object index) { + protected boolean isExist(Object index) { return (Integer) index >= 0; } diff --git a/src/com/learnjava/storage/AbstractStorage.java b/src/com/learnjava/storage/AbstractStorage.java index 389f5c3..eb0e3ed 100644 --- a/src/com/learnjava/storage/AbstractStorage.java +++ b/src/com/learnjava/storage/AbstractStorage.java @@ -6,39 +6,39 @@ public abstract class AbstractStorage implements Storage { protected abstract Object getSearchKey(String uuid); - protected abstract void Update(Resume r, Object searchKey); + protected abstract void doUpdate(Resume r, Object searchKey); - protected abstract boolean Exist(Object searchKey); + protected abstract boolean isExist(Object searchKey); - protected abstract void Save(Resume r, Object searchKey); + protected abstract void doSave(Resume r, Object searchKey); - protected abstract Resume getResume(Object searchKey); + protected abstract Resume doGet(Object searchKey); - protected abstract void Delete(Object searchKey); + protected abstract void doDelete(Object searchKey); public void update(Resume r) { Object searchKey = getExistedSearchKey(r.getUuid()); - Update(r, searchKey); + doUpdate(r, searchKey); } public void save(Resume r) { Object searchKey = getNotExistedSearchKey(r.getUuid()); - Save(r, searchKey); + doSave(r, searchKey); } public void delete(String uuid) { Object searchKey = getExistedSearchKey(uuid); - Delete(searchKey); + doDelete(searchKey); } public Resume get(String uuid) { Object searchKey = getExistedSearchKey(uuid); - return getResume(searchKey); + return doGet(searchKey); } private Object getExistedSearchKey(String uuid) { Object searchKey = getSearchKey(uuid); - if (!Exist(searchKey)) { + if (!isExist(searchKey)) { throw new NotExistStorageException(uuid); } return searchKey; @@ -46,7 +46,7 @@ private Object getExistedSearchKey(String uuid) { private Object getNotExistedSearchKey(String uuid) { Object searchKey = getSearchKey(uuid); - if (Exist(searchKey)) { + if (isExist(searchKey)) { throw new ExistStorageException(uuid); } return searchKey; diff --git a/src/com/learnjava/storage/ListStorage.java b/src/com/learnjava/storage/ListStorage.java index b2dfe49..2fe21c0 100644 --- a/src/com/learnjava/storage/ListStorage.java +++ b/src/com/learnjava/storage/ListStorage.java @@ -19,27 +19,27 @@ protected Integer getSearchKey(String uuid) { } @Override - protected boolean Exist(Object searchKey) { + protected boolean isExist(Object searchKey) { return searchKey != null; } @Override - protected void Update(Resume r, Object searchKey) { + protected void doUpdate(Resume r, Object searchKey) { list.set((Integer) searchKey, r); } @Override - protected void Save(Resume r, Object searchKey) { + protected void doSave(Resume r, Object searchKey) { list.add(r); } @Override - protected Resume getResume(Object searchKey) { + protected Resume doGet(Object searchKey) { return list.get((Integer) searchKey); } @Override - protected void Delete(Object searchKey) { + protected void doDelete(Object searchKey) { list.remove(((Integer) searchKey).intValue()); } @@ -50,7 +50,7 @@ public void clear() { @Override public Resume[] getAll() { - return list.toArray(new Resume[list.size()]); + return list.toArray(new Resume[0]); } @Override diff --git a/src/com/learnjava/storage/MapStorage.java b/src/com/learnjava/storage/MapStorage.java new file mode 100644 index 0000000..727e8f4 --- /dev/null +++ b/src/com/learnjava/storage/MapStorage.java @@ -0,0 +1,59 @@ +package com.learnjava.storage; + +import com.learnjava.model.Resume; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class MapStorage extends AbstractStorage { + private Map map = new HashMap<>(); + + + @Override + protected String getSearchKey(String uuid) { + return uuid; + } + + @Override + protected void doUpdate(Resume r, Object searchKey) { + map.put((String) searchKey, r); + } + + @Override + protected boolean isExist(Object searchKey) { + return map.containsKey((String) searchKey); + } + + @Override + protected void doSave(Resume r, Object searchKey) { + map.put((String) searchKey, r); + } + + @Override + protected Resume doGet(Object searchKey) { + return map.get((String) searchKey); + } + + @Override + protected void doDelete(Object searchKey) { + map.remove((String) searchKey); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public Resume[] getAll() { + Resume[] array = map.values().toArray(new Resume[0]); + Arrays.sort(array); + return array; + } + + @Override + public int size() { + return map.size(); + } +} diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 4c000ad..5688f45 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -9,7 +9,7 @@ public abstract class AbstractStorageTest { protected Storage storage; protected Storage emptyStorage; - protected boolean overflowApplicable; + protected boolean overflowApplicable = true; private static final String UUID_1 = "uuid1"; private static final Resume RESUME_1 = new Resume(UUID_1); diff --git a/test/com/learnjava/storage/MapStorageTest.java b/test/com/learnjava/storage/MapStorageTest.java new file mode 100644 index 0000000..55ef8eb --- /dev/null +++ b/test/com/learnjava/storage/MapStorageTest.java @@ -0,0 +1,8 @@ +package com.learnjava.storage; + +public class MapStorageTest extends AbstractStorageTest { + public MapStorageTest(){ + super(new MapStorage(), new MapStorage()); + overflowApplicable = false; + } +} From fd630eb3aba07515a69e62f8a177cc49430619d2 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:56:53 +0300 Subject: [PATCH 45/71] =?UTF-8?q?HW05=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/storage/MapStorage.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/com/learnjava/storage/MapStorage.java b/src/com/learnjava/storage/MapStorage.java index 727e8f4..f19ee0b 100644 --- a/src/com/learnjava/storage/MapStorage.java +++ b/src/com/learnjava/storage/MapStorage.java @@ -7,8 +7,7 @@ import java.util.Map; public class MapStorage extends AbstractStorage { - private Map map = new HashMap<>(); - + private final Map map = new HashMap<>(); @Override protected String getSearchKey(String uuid) { From 67faa9a60dc6d8cf03f3b7c5a204c30725b59dfc Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:17:17 +0300 Subject: [PATCH 46/71] =?UTF-8?q?HW06=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=BE=20=D0=B4=D0=B7=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainArray.java | 23 +++---- src/com/learnjava/MainTestArrayStorage.java | 2 +- src/com/learnjava/model/Resume.java | 22 ++++--- .../storage/AbstractArrayStorage.java | 5 +- .../learnjava/storage/AbstractStorage.java | 12 ++++ src/com/learnjava/storage/ListStorage.java | 4 +- src/com/learnjava/storage/MapStorage.java | 11 ++-- .../learnjava/storage/SortedArrayStorage.java | 12 ++-- src/com/learnjava/storage/Storage.java | 7 ++- .../storage/AbstractArrayStorageTest.java | 22 +++++++ .../storage/AbstractStorageTest.java | 61 ++++++------------- .../learnjava/storage/ArrayStorageTest.java | 3 +- .../learnjava/storage/ListStorageTest.java | 2 - .../com/learnjava/storage/MapStorageTest.java | 1 - .../storage/SortedArrayStorageTest.java | 3 +- .../learnjava/storage/everyStorageTest.java | 16 +++++ 16 files changed, 120 insertions(+), 86 deletions(-) create mode 100644 test/com/learnjava/storage/AbstractArrayStorageTest.java create mode 100644 test/com/learnjava/storage/everyStorageTest.java diff --git a/src/com/learnjava/MainArray.java b/src/com/learnjava/MainArray.java index 25d7675..8aef8aa 100644 --- a/src/com/learnjava/MainArray.java +++ b/src/com/learnjava/MainArray.java @@ -5,6 +5,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.List; /** * Interactive test for ArrayStorage implementation @@ -17,15 +18,15 @@ public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Resume r; while (true) { - System.out.print("Введите одну из команд - (list | save uuid | delete uuid | get uuid | update uuid | clear | exit): "); + System.out.print("Введите одну из команд - (list | save name | delete uuid | get uuid | update uuid | clear | exit): "); String[] params = reader.readLine().trim().toLowerCase().split(" "); - if (params.length < 1 || params.length > 2) { + if (params.length < 1 || params.length > 3) { System.out.println("Неверная команда."); continue; } - String uuid = null; - if (params.length == 2) { - uuid = params[1].intern(); + String param = null; + if (params.length > 1) { + param = params[1].intern(); } switch (params[0]) { case "list": @@ -35,21 +36,21 @@ public static void main(String[] args) throws IOException { System.out.println(ARRAY_STORAGE.size()); break; case "save": - r = new Resume(uuid); + r = new Resume(param); ARRAY_STORAGE.save(r); printAll(); break; case "update": - r = new Resume(uuid); + r = new Resume(param, params[2]); ARRAY_STORAGE.update(r); printAll(); break; case "delete": - ARRAY_STORAGE.delete(uuid); + ARRAY_STORAGE.delete(param); printAll(); break; case "get": - System.out.println(ARRAY_STORAGE.get(uuid)); + System.out.println(ARRAY_STORAGE.get(param)); break; case "clear": ARRAY_STORAGE.clear(); @@ -65,9 +66,9 @@ public static void main(String[] args) throws IOException { } static void printAll() { - Resume[] all = ARRAY_STORAGE.getAll(); + List all = ARRAY_STORAGE.getAllSorted(); System.out.println("----------------------------"); - if (all.length == 0) { + if (all.size() == 0) { System.out.println("Empty"); } else { for (Resume r : all) { diff --git a/src/com/learnjava/MainTestArrayStorage.java b/src/com/learnjava/MainTestArrayStorage.java index 00c85b9..8357c71 100644 --- a/src/com/learnjava/MainTestArrayStorage.java +++ b/src/com/learnjava/MainTestArrayStorage.java @@ -34,7 +34,7 @@ public static void main(String[] args) { static void printAll() { System.out.println("\nGet All"); - for (Resume r : ARRAY_STORAGE.getAll()) { + for (Resume r : ARRAY_STORAGE.getAllSorted()) { System.out.println(r); } } diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index 01c6680..3e67e37 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -1,6 +1,6 @@ package com.learnjava.model; - +import java.util.Objects; import java.util.UUID; /** @@ -10,13 +10,15 @@ public class Resume implements Comparable { // Unique identifier private final String uuid; + private final String fullName; - public Resume() { - this(UUID.randomUUID().toString()); + public Resume(String fullName) { + this(UUID.randomUUID().toString(), fullName); } - public Resume(String uuid) { + public Resume(String uuid, String fullName) { this.uuid = uuid; + this.fullName = fullName; } public String getUuid() { @@ -27,24 +29,24 @@ public String getUuid() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Resume resume = (Resume) o; - - return uuid.equals(resume.uuid); + if (!uuid.equals(resume.uuid)) return false; + return fullName.equals(resume.fullName); } @Override public int hashCode() { - return uuid.hashCode(); + return Objects.hash(this.uuid, this.fullName); } @Override public String toString() { - return uuid; + return uuid + ' ' + fullName; } @Override public int compareTo(Resume o) { - return uuid.compareTo(o.uuid); + int compareFullName = fullName.compareTo(o.fullName); + return compareFullName == 0 ? uuid.compareTo(o.uuid) : compareFullName; } } \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractArrayStorage.java b/src/com/learnjava/storage/AbstractArrayStorage.java index 96e4956..32a92a1 100644 --- a/src/com/learnjava/storage/AbstractArrayStorage.java +++ b/src/com/learnjava/storage/AbstractArrayStorage.java @@ -4,6 +4,7 @@ import com.learnjava.model.Resume; import java.util.Arrays; +import java.util.List; /** @@ -30,8 +31,8 @@ protected void doUpdate(Resume r, Object index) { } - public Resume[] getAll() { - return Arrays.copyOfRange(storage, 0, size); + public List doCopyAll() { + return Arrays.asList(Arrays.copyOfRange(storage, 0, size)); } @Override diff --git a/src/com/learnjava/storage/AbstractStorage.java b/src/com/learnjava/storage/AbstractStorage.java index eb0e3ed..d5f5441 100644 --- a/src/com/learnjava/storage/AbstractStorage.java +++ b/src/com/learnjava/storage/AbstractStorage.java @@ -1,8 +1,12 @@ package com.learnjava.storage; + import com.learnjava.exception.ExistStorageException; import com.learnjava.exception.NotExistStorageException; import com.learnjava.model.Resume; +import java.util.Collections; +import java.util.List; + public abstract class AbstractStorage implements Storage { protected abstract Object getSearchKey(String uuid); @@ -16,6 +20,8 @@ public abstract class AbstractStorage implements Storage { protected abstract void doDelete(Object searchKey); + protected abstract List doCopyAll(); + public void update(Resume r) { Object searchKey = getExistedSearchKey(r.getUuid()); doUpdate(r, searchKey); @@ -51,4 +57,10 @@ private Object getNotExistedSearchKey(String uuid) { } return searchKey; } + @Override + public List getAllSorted() { + List list = doCopyAll(); + Collections.sort(list); + return list; + } } diff --git a/src/com/learnjava/storage/ListStorage.java b/src/com/learnjava/storage/ListStorage.java index 2fe21c0..c600304 100644 --- a/src/com/learnjava/storage/ListStorage.java +++ b/src/com/learnjava/storage/ListStorage.java @@ -49,8 +49,8 @@ public void clear() { } @Override - public Resume[] getAll() { - return list.toArray(new Resume[0]); + public List doCopyAll() { + return new ArrayList<>(list); } @Override diff --git a/src/com/learnjava/storage/MapStorage.java b/src/com/learnjava/storage/MapStorage.java index f19ee0b..503c569 100644 --- a/src/com/learnjava/storage/MapStorage.java +++ b/src/com/learnjava/storage/MapStorage.java @@ -2,9 +2,10 @@ import com.learnjava.model.Resume; -import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.ArrayList; public class MapStorage extends AbstractStorage { private final Map map = new HashMap<>(); @@ -44,13 +45,11 @@ public void clear() { map.clear(); } + @Override - public Resume[] getAll() { - Resume[] array = map.values().toArray(new Resume[0]); - Arrays.sort(array); - return array; + public List doCopyAll() { + return new ArrayList<>(map.values()); } - @Override public int size() { return map.size(); diff --git a/src/com/learnjava/storage/SortedArrayStorage.java b/src/com/learnjava/storage/SortedArrayStorage.java index 8ab7a1c..d3ce380 100644 --- a/src/com/learnjava/storage/SortedArrayStorage.java +++ b/src/com/learnjava/storage/SortedArrayStorage.java @@ -1,10 +1,14 @@ package com.learnjava.storage; -import com.learnjava.model.*; -import java.util.Arrays; + +import com.learnjava.model.Resume; + +import java.util.Arrays; +import java.util.Comparator; public class SortedArrayStorage extends AbstractArrayStorage { + private static final Comparator RESUME_COMPARATOR = Comparator.comparing(Resume::getUuid); @Override protected void fillDeletedElement(int index) { int numMoved = size - index - 1; @@ -23,7 +27,7 @@ protected void insertElement(Resume r, int index) { @Override protected Integer getSearchKey(String uuid) { - Resume searchKey = new Resume(uuid); - return Arrays.binarySearch(storage, 0, size, searchKey); + Resume searchKey = new Resume(uuid, "dummy"); + return Arrays.binarySearch(storage, 0, size, searchKey, RESUME_COMPARATOR); } } \ No newline at end of file diff --git a/src/com/learnjava/storage/Storage.java b/src/com/learnjava/storage/Storage.java index c087948..e77472e 100644 --- a/src/com/learnjava/storage/Storage.java +++ b/src/com/learnjava/storage/Storage.java @@ -1,5 +1,8 @@ package com.learnjava.storage; -import com.learnjava.model.*; + +import com.learnjava.model.Resume; + +import java.util.List; public interface Storage { @@ -13,7 +16,7 @@ public interface Storage { void delete(String uuid); - Resume[] getAll(); + List getAllSorted(); int size(); } \ No newline at end of file diff --git a/test/com/learnjava/storage/AbstractArrayStorageTest.java b/test/com/learnjava/storage/AbstractArrayStorageTest.java new file mode 100644 index 0000000..709a9ab --- /dev/null +++ b/test/com/learnjava/storage/AbstractArrayStorageTest.java @@ -0,0 +1,22 @@ +package com.learnjava.storage; + +import com.learnjava.exception.StorageException; +import com.learnjava.model.Resume; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public abstract class AbstractArrayStorageTest extends AbstractStorageTest { + protected AbstractArrayStorageTest(Storage storage, Storage emptyStorage) { + super(storage, emptyStorage); + } + @Test + void overflow() { + storage.clear(); + for (int i = 0; i < AbstractArrayStorage.STORAGE_LIMIT; i++) { + storage.save(new Resume("dummy" + i )); + } + Assertions.assertThrows(StorageException.class, () -> storage.save(new Resume("full dummy"))); + + } +} + diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 5688f45..628bd4f 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -1,29 +1,32 @@ package com.learnjava.storage; + import com.learnjava.exception.NotExistStorageException; -import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Arrays; +import java.util.List; + public abstract class AbstractStorageTest { protected Storage storage; protected Storage emptyStorage; - protected boolean overflowApplicable = true; + private static final String UUID_1 = "uuid1"; - private static final Resume RESUME_1 = new Resume(UUID_1); + private static final Resume RESUME_1 = new Resume(UUID_1, "Ivanov"); private static final String UUID_2 = "uuid2"; - private static final Resume RESUME_2 = new Resume(UUID_2); + private static final Resume RESUME_2 = new Resume(UUID_2,"Petrov"); private static final String UUID_3 = "uuid3"; - private static final Resume RESUME_3 = new Resume(UUID_3); + private static final Resume RESUME_3 = new Resume(UUID_3,"Sidorov"); private static final String UUID_4 = "extra_uuid"; - private static final Resume RESUME_4 = new Resume(UUID_4); + private static final Resume RESUME_4 = new Resume(UUID_4,"Kuznetcov"); private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; - private static final Resume RESUME_5 = new Resume(UUID_NOT_EXIST); + private static final Resume RESUME_5 = new Resume(UUID_NOT_EXIST,"Gzhegosh"); protected AbstractStorageTest(Storage storage, Storage emptyStorage) { this.storage = storage; @@ -59,23 +62,21 @@ void size() { void clear() { storage.clear(); assertSize(0); - Assertions.assertArrayEquals(storage.getAll(), emptyStorage.getAll()); + Assertions.assertArrayEquals(storage.getAllSorted().toArray(), emptyStorage.getAllSorted().toArray()); } @Test void update() { - Resume newResume = new Resume(UUID_1); + Resume newResume = new Resume(UUID_1,"Ivanov"); storage.update(newResume); Assertions.assertSame(newResume, storage.get(UUID_1)); } @Test - void getAll() { - Resume[] array = storage.getAll(); - Assertions.assertEquals(3, array.length); - Assertions.assertEquals(RESUME_1, array[0]); - Assertions.assertEquals(RESUME_2, array[1]); - Assertions.assertEquals(RESUME_3, array[2]); + void getAllSorted() { + List list = storage.getAllSorted(); + Assertions.assertEquals(3, list.size()); + Assertions.assertEquals(list, Arrays.asList(RESUME_1, RESUME_2, RESUME_3)); } @Test @@ -85,31 +86,15 @@ void save() { assertGet(RESUME_4); } - @Test - void overflow() { - if (overflowApplicable) { - storage.clear(); - for (int i = 0; i < AbstractArrayStorage.STORAGE_LIMIT; i++) { - storage.save(new Resume()); - } - Assertions.assertThrows(StorageException.class, () -> { - storage.save(new Resume()); - }); - } - } - @Test void delete() { storage.delete(UUID_1); assertSize(2); - Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.get(UUID_1); - }); + Assertions.assertThrows(NotExistStorageException.class, () -> storage.get(UUID_1)); } @Test void get() { - assertGet(RESUME_1); assertGet(RESUME_2); assertGet(RESUME_3); @@ -117,22 +102,16 @@ void get() { @Test void getNotExist() { - Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.get(UUID_NOT_EXIST); - }); + Assertions.assertThrows(NotExistStorageException.class, () -> storage.get(UUID_NOT_EXIST)); } @Test void deleteNotExist() { - Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.delete(UUID_NOT_EXIST); - }); + Assertions.assertThrows(NotExistStorageException.class, () -> storage.delete(UUID_NOT_EXIST)); } @Test public void updateNotExist() { - Assertions.assertThrows(NotExistStorageException.class, () -> { - storage.update(RESUME_5); - }); + Assertions.assertThrows(NotExistStorageException.class, () -> storage.update(RESUME_5)); } } diff --git a/test/com/learnjava/storage/ArrayStorageTest.java b/test/com/learnjava/storage/ArrayStorageTest.java index 92b7d38..4375ce6 100644 --- a/test/com/learnjava/storage/ArrayStorageTest.java +++ b/test/com/learnjava/storage/ArrayStorageTest.java @@ -1,10 +1,9 @@ package com.learnjava.storage; -public class ArrayStorageTest extends AbstractStorageTest { +public class ArrayStorageTest extends AbstractArrayStorageTest { public ArrayStorageTest() { super(new ArrayStorage(), new ArrayStorage()); - super.overflowApplicable = true; } } \ No newline at end of file diff --git a/test/com/learnjava/storage/ListStorageTest.java b/test/com/learnjava/storage/ListStorageTest.java index 370bc0a..6a07954 100644 --- a/test/com/learnjava/storage/ListStorageTest.java +++ b/test/com/learnjava/storage/ListStorageTest.java @@ -3,7 +3,5 @@ public class ListStorageTest extends AbstractStorageTest { public ListStorageTest() { super(new ListStorage(), new ListStorage() ); - super.overflowApplicable = false; } - } \ No newline at end of file diff --git a/test/com/learnjava/storage/MapStorageTest.java b/test/com/learnjava/storage/MapStorageTest.java index 55ef8eb..0392669 100644 --- a/test/com/learnjava/storage/MapStorageTest.java +++ b/test/com/learnjava/storage/MapStorageTest.java @@ -3,6 +3,5 @@ public class MapStorageTest extends AbstractStorageTest { public MapStorageTest(){ super(new MapStorage(), new MapStorage()); - overflowApplicable = false; } } diff --git a/test/com/learnjava/storage/SortedArrayStorageTest.java b/test/com/learnjava/storage/SortedArrayStorageTest.java index 613b80e..76cd9d2 100644 --- a/test/com/learnjava/storage/SortedArrayStorageTest.java +++ b/test/com/learnjava/storage/SortedArrayStorageTest.java @@ -1,10 +1,9 @@ package com.learnjava.storage; -public class SortedArrayStorageTest extends AbstractStorageTest { +public class SortedArrayStorageTest extends AbstractArrayStorageTest { public SortedArrayStorageTest() { super(new SortedArrayStorage(), new SortedArrayStorage()); - super.overflowApplicable = true; } } \ No newline at end of file diff --git a/test/com/learnjava/storage/everyStorageTest.java b/test/com/learnjava/storage/everyStorageTest.java new file mode 100644 index 0000000..5f4d05c --- /dev/null +++ b/test/com/learnjava/storage/everyStorageTest.java @@ -0,0 +1,16 @@ +package com.learnjava.storage; + +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectClasses({ + ArrayStorageTest.class, + SortedArrayStorageTest.class, + ListStorageTest.class, + MapStorageTest.class + +}) +public class everyStorageTest { + +} From 20438f57ac2cac91e3cc290abcf45b927eed02c6 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Thu, 27 Jul 2023 10:40:30 +0300 Subject: [PATCH 47/71] =?UTF-8?q?HW06=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20MapUUIDStorage=20=D0=B8=20=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=20=D1=82=D0=B5=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/storage/MapUUIDStorage.java | 56 +++++++++++++++++++ .../learnjava/storage/MapUUIDStorageTest.java | 7 +++ .../learnjava/storage/everyStorageTest.java | 4 +- 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/com/learnjava/storage/MapUUIDStorage.java create mode 100644 test/com/learnjava/storage/MapUUIDStorageTest.java diff --git a/src/com/learnjava/storage/MapUUIDStorage.java b/src/com/learnjava/storage/MapUUIDStorage.java new file mode 100644 index 0000000..93f99d1 --- /dev/null +++ b/src/com/learnjava/storage/MapUUIDStorage.java @@ -0,0 +1,56 @@ +package com.learnjava.storage; + +import com.learnjava.model.Resume; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MapUUIDStorage extends AbstractStorage { + private final Map map = new HashMap<>(); + + @Override + protected String getSearchKey(String uuid) { + return uuid; + } + + @Override + protected void doUpdate(Resume r, Object uuid) { + map.put((String) uuid, r); + } + @Override + protected boolean isExist(Object uuid) { + return map.containsKey((String) uuid); + } + + @Override + protected void doSave(Resume r, Object uuid) { + map.put((String) uuid, r); + } + + @Override + protected Resume doGet(Object uuid) { + return map.get((String) uuid); + } + + @Override + protected void doDelete(Object uuid) { + map.remove((String) uuid); + } + + @Override + public void clear() { + map.clear(); + } + + + @Override + public List doCopyAll() { + return new ArrayList<>(map.values()); + } + @Override + public int size() { + return map.size(); + } +} diff --git a/test/com/learnjava/storage/MapUUIDStorageTest.java b/test/com/learnjava/storage/MapUUIDStorageTest.java new file mode 100644 index 0000000..07443e0 --- /dev/null +++ b/test/com/learnjava/storage/MapUUIDStorageTest.java @@ -0,0 +1,7 @@ +package com.learnjava.storage; + +public class MapUUIDStorageTest extends AbstractStorageTest { + public MapUUIDStorageTest(){ + super(new MapUUIDStorage(), new MapUUIDStorage()); + } +} diff --git a/test/com/learnjava/storage/everyStorageTest.java b/test/com/learnjava/storage/everyStorageTest.java index 5f4d05c..8006444 100644 --- a/test/com/learnjava/storage/everyStorageTest.java +++ b/test/com/learnjava/storage/everyStorageTest.java @@ -8,8 +8,8 @@ ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, - MapStorageTest.class - + MapStorageTest.class, + MapUUIDStorageTest.class }) public class everyStorageTest { From 7d50ae6d40b0a75c50ea7546c073c7d2734e401e Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Thu, 27 Jul 2023 10:47:44 +0300 Subject: [PATCH 48/71] =?UTF-8?q?HW06=20=D1=81=D0=BE=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7?= =?UTF-8?q?=20list.sort,=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=20MapUUIDStorage=20=D0=B8=20=D0=B5=D0=B3=D0=BE=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/storage/AbstractStorage.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/learnjava/storage/AbstractStorage.java b/src/com/learnjava/storage/AbstractStorage.java index d5f5441..655681c 100644 --- a/src/com/learnjava/storage/AbstractStorage.java +++ b/src/com/learnjava/storage/AbstractStorage.java @@ -4,7 +4,7 @@ import com.learnjava.exception.NotExistStorageException; import com.learnjava.model.Resume; -import java.util.Collections; +import java.util.Comparator; import java.util.List; public abstract class AbstractStorage implements Storage { @@ -21,7 +21,7 @@ public abstract class AbstractStorage implements Storage { protected abstract void doDelete(Object searchKey); protected abstract List doCopyAll(); - + private static final Comparator RESUME_COMPARATOR = Comparator.comparing(Resume::getUuid); public void update(Resume r) { Object searchKey = getExistedSearchKey(r.getUuid()); doUpdate(r, searchKey); @@ -60,7 +60,7 @@ private Object getNotExistedSearchKey(String uuid) { @Override public List getAllSorted() { List list = doCopyAll(); - Collections.sort(list); + list.sort(RESUME_COMPARATOR); return list; } } From 1c958a5741f0c88913889800c6c0e15e3bc4da2a Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Thu, 27 Jul 2023 16:03:45 +0300 Subject: [PATCH 49/71] =?UTF-8?q?HW06=20MapStorage=20=D1=82=D0=B5=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D1=8C=20=D0=B4=D0=B5=D0=BB=D0=B0=D0=B5=D1=82=20map?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B7=D1=8E=D0=BC=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/storage/MapStorage.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/com/learnjava/storage/MapStorage.java b/src/com/learnjava/storage/MapStorage.java index 503c569..89d27d8 100644 --- a/src/com/learnjava/storage/MapStorage.java +++ b/src/com/learnjava/storage/MapStorage.java @@ -11,33 +11,33 @@ public class MapStorage extends AbstractStorage { private final Map map = new HashMap<>(); @Override - protected String getSearchKey(String uuid) { - return uuid; + protected Resume getSearchKey(String uuid) { + return map.get(uuid); } @Override protected void doUpdate(Resume r, Object searchKey) { - map.put((String) searchKey, r); + map.put(r.getUuid(), r); } @Override protected boolean isExist(Object searchKey) { - return map.containsKey((String) searchKey); + return searchKey != null; } @Override protected void doSave(Resume r, Object searchKey) { - map.put((String) searchKey, r); + map.put(r.getUuid(), r); } @Override protected Resume doGet(Object searchKey) { - return map.get((String) searchKey); + return (Resume) searchKey; } @Override protected void doDelete(Object searchKey) { - map.remove((String) searchKey); + map.remove(((Resume) searchKey).getUuid()); } @Override @@ -45,11 +45,11 @@ public void clear() { map.clear(); } - @Override public List doCopyAll() { return new ArrayList<>(map.values()); } + @Override public int size() { return map.size(); From bad3238e988d69072a4ff969347ed5db88191144 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Sun, 30 Jul 2023 13:05:48 +0300 Subject: [PATCH 50/71] =?UTF-8?q?HW07=20IML=20=D0=B4=D0=B8=D0=B0=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=D0=BC=D0=B0=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0,=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D1=81=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=BE=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D1=81=D0=BF=D0=BE=D1=81=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20ResumeTestData=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 45 ++++++++++++++ src/com/learnjava/model/ContactType.java | 22 +++++++ src/com/learnjava/model/Experience.java | 61 +++++++++++++++++++ .../learnjava/model/ExperienceSection.java | 38 ++++++++++++ src/com/learnjava/model/Link.java | 46 ++++++++++++++ src/com/learnjava/model/ListSection.java | 38 ++++++++++++ src/com/learnjava/model/Resume.java | 24 +++++++- src/com/learnjava/model/Section.java | 4 ++ src/com/learnjava/model/SectionType.java | 20 ++++++ src/com/learnjava/model/TextSection.java | 30 +++++++++ 10 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 src/com/learnjava/ResumeTestData.java create mode 100644 src/com/learnjava/model/ContactType.java create mode 100644 src/com/learnjava/model/Experience.java create mode 100644 src/com/learnjava/model/ExperienceSection.java create mode 100644 src/com/learnjava/model/Link.java create mode 100644 src/com/learnjava/model/ListSection.java create mode 100644 src/com/learnjava/model/Section.java create mode 100644 src/com/learnjava/model/SectionType.java create mode 100644 src/com/learnjava/model/TextSection.java diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java new file mode 100644 index 0000000..19d454f --- /dev/null +++ b/src/com/learnjava/ResumeTestData.java @@ -0,0 +1,45 @@ +package com.learnjava; + +import com.learnjava.model.*; + +import java.time.LocalDate; +import java.util.Arrays; + +import static com.learnjava.model.ContactType.*; +import static com.learnjava.model.SectionType.*; + +public class ResumeTestData { + + private static Resume resume; + + private ResumeTestData() { + } + + public static void fillResumeTestData() { + resume = new Resume("Grigoriy Kislicyn"); + resume.addContact(MOBILE, "+7(921) 855-0482 "); + resume.addContact(SKYPE, "skype:grigory.kislin"); + resume.addContact(MAIL, "gkislin@yandex.ru"); + resume.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); + resume.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); + resume.addSection(SectionType.EXPERIENCE, new ExperienceSection(Arrays.asList( + new Experience("Java Online Projects", "https://javaops.ru/", LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок.") + , new Experience("Wrike", "https://www.wrike.com/aa/", LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))); + } + + + public static void printResumeTestData() { + System.out.println("uuid and full name: " + resume.toString()); + System.out.println(MOBILE.getTitle() + " : " + resume.getContact(MOBILE)); + System.out.println(SKYPE.getTitle() + " : " + resume.getContact(SKYPE)); + System.out.println(MAIL.getTitle() + " : " + resume.getContact(MAIL)); + System.out.println(OBJECTIVE.getTitle() + " : " + resume.getSection(OBJECTIVE).toString()); + System.out.println(ACHIEVEMENT.getTitle() + " : " + resume.getSection(ACHIEVEMENT).toString()); + System.out.println(EXPERIENCE.getTitle() + " : " + resume.getSection(EXPERIENCE).toString()); + } + + public static void main(String[] args) { + fillResumeTestData(); + printResumeTestData(); + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/ContactType.java b/src/com/learnjava/model/ContactType.java new file mode 100644 index 0000000..cde83ab --- /dev/null +++ b/src/com/learnjava/model/ContactType.java @@ -0,0 +1,22 @@ +package com.learnjava.model; + +public enum ContactType { + + MOBILE("Мобильный"), + SKYPE("Skype"), + MAIL("Почта"), + LINKEDIN("Профиль LinkedIn"), + GITHUB("Профиль GitHub"), + STATCKOVERFLOW("Профиль Stackoverflow"), + HOME_PAGE("Домашняя страница"); + + private final String title; + + ContactType(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/Experience.java b/src/com/learnjava/model/Experience.java new file mode 100644 index 0000000..1819cb2 --- /dev/null +++ b/src/com/learnjava/model/Experience.java @@ -0,0 +1,61 @@ +package com.learnjava.model; + +import java.time.LocalDate; +import java.util.Objects; + +public class Experience { + private final String Organization; + private final Link homePage; + private final LocalDate startDate; + private final LocalDate endDate; + private final String title; + private final String description; + + public Experience(String name, String url, LocalDate startDate, LocalDate endDate, String title, String description) { + this.Organization = name; + this.homePage = new Link(name, url); + this.startDate = startDate; + this.endDate = endDate; + this.title = title; + this.description = description; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Experience that = (Experience) o; + + if (!Organization.equals(that.Organization)) return false; + if (!homePage.equals(that.homePage)) return false; + if (!startDate.equals(that.startDate)) return false; + if (!endDate.equals(that.endDate)) return false; + if (!title.equals(that.title)) return false; + return Objects.equals(description, that.description); + + } + + @Override + public int hashCode() { + int result = homePage.hashCode(); + result = 31 * result + Organization.hashCode(); + result = 31 * result + startDate.hashCode(); + result = 31 * result + endDate.hashCode(); + result = 31 * result + title.hashCode(); + result = 31 * result + (description != null ? description.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "\n Organization{" + + Organization + + ", homePage=" + homePage + + ", startDate=" + startDate + + ", endDate=" + endDate + + ", title='" + title + '\'' + + ", description='" + description + '\'' + + "}"; + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/ExperienceSection.java b/src/com/learnjava/model/ExperienceSection.java new file mode 100644 index 0000000..08ca65b --- /dev/null +++ b/src/com/learnjava/model/ExperienceSection.java @@ -0,0 +1,38 @@ +package com.learnjava.model; + +import java.util.List; +import java.util.Objects; + +public class ExperienceSection extends Section { + private final List Experiences; + + public ExperienceSection(List Experiences) { + Objects.requireNonNull(Experiences, "Experiences must not be null"); + this.Experiences = Experiences; + } + + public List getExperiences() { + return Experiences; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExperienceSection that = (ExperienceSection) o; + + return Experiences.equals(that.Experiences); + + } + + @Override + public int hashCode() { + return Experiences.hashCode(); + } + + @Override + public String toString() { + return Experiences.toString(); + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/Link.java b/src/com/learnjava/model/Link.java new file mode 100644 index 0000000..4c19132 --- /dev/null +++ b/src/com/learnjava/model/Link.java @@ -0,0 +1,46 @@ +package com.learnjava.model; + +import java.util.Objects; + +public class Link { + private final String name; + private final String url; + + + public Link(String name, String url) { + this.name = name; + this.url = url; + } + + public String getName() { + return name; + } + + public String getUrl() { + return url; + } + + @Override + public String toString() { + return "Link(" + name + ',' + url + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Link link = (Link) o; + + if (!name.equals(link.name)) return false; + return Objects.equals(url, link.url); + + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + (url != null ? url.hashCode() : 0); + return result; + } +} diff --git a/src/com/learnjava/model/ListSection.java b/src/com/learnjava/model/ListSection.java new file mode 100644 index 0000000..3a19de0 --- /dev/null +++ b/src/com/learnjava/model/ListSection.java @@ -0,0 +1,38 @@ +package com.learnjava.model; + +import java.util.List; +import java.util.Objects; + +public class ListSection extends Section { + private final List items; + + public ListSection(List items) { + Objects.requireNonNull(items, "items must not be null"); + this.items = items; + } + + public List getItems() { + return items; + } + + @Override + public String toString() { + return items.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ListSection that = (ListSection) o; + + return items.equals(that.items); + + } + + @Override + public int hashCode() { + return items.hashCode(); + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index 3e67e37..5ddf613 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -2,6 +2,8 @@ import java.util.Objects; import java.util.UUID; +import java.util.EnumMap; +import java.util.Map; /** * ru.javawebinar.basejava.model.Resume class @@ -12,6 +14,9 @@ public class Resume implements Comparable { private final String uuid; private final String fullName; + private final Map contacts = new EnumMap<>(ContactType.class); + private final Map sections = new EnumMap<>(SectionType.class); + public Resume(String fullName) { this(UUID.randomUUID().toString(), fullName); } @@ -21,6 +26,23 @@ public Resume(String uuid, String fullName) { this.fullName = fullName; } + public String getContact(ContactType type) { + return contacts.get(type); + } + + public Section getSection(SectionType type) { + return sections.get(type); + } + + public void addContact(ContactType type, String value) { + contacts.put(type, value); + } + + public void addSection(SectionType type, Section section) { + sections.put(type, section); + } + + public String getUuid() { return uuid; } @@ -47,6 +69,6 @@ public String toString() { @Override public int compareTo(Resume o) { int compareFullName = fullName.compareTo(o.fullName); - return compareFullName == 0 ? uuid.compareTo(o.uuid) : compareFullName; + return compareFullName == 0 ? uuid.compareTo(o.uuid) : compareFullName; } } \ No newline at end of file diff --git a/src/com/learnjava/model/Section.java b/src/com/learnjava/model/Section.java new file mode 100644 index 0000000..f2ea793 --- /dev/null +++ b/src/com/learnjava/model/Section.java @@ -0,0 +1,4 @@ +package com.learnjava.model; + +abstract public class Section { +} diff --git a/src/com/learnjava/model/SectionType.java b/src/com/learnjava/model/SectionType.java new file mode 100644 index 0000000..3aa7a85 --- /dev/null +++ b/src/com/learnjava/model/SectionType.java @@ -0,0 +1,20 @@ +package com.learnjava.model; + +public enum SectionType { + OBJECTIVE("Позиция"), + PERSONAL("Личные качества"), + ACHIEVEMENT("Достижения"), + QUALIFICATIONS("Квалификация"), + EXPERIENCE("Опыт работы"), + EDUCATION("Образование"); + + private String title; + + SectionType(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } +} diff --git a/src/com/learnjava/model/TextSection.java b/src/com/learnjava/model/TextSection.java new file mode 100644 index 0000000..a388376 --- /dev/null +++ b/src/com/learnjava/model/TextSection.java @@ -0,0 +1,30 @@ +package com.learnjava.model; + +public class TextSection extends Section { + private final String content; + + public TextSection(String content) { + this.content = content; + } + + @Override + public String toString() { + return content; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TextSection that = (TextSection) o; + + return content.equals(that.content); + + } + + @Override + public int hashCode() { + return content.hashCode(); + } +} \ No newline at end of file From e78b94227c1f9be3648093436f39590f35385df9 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Sun, 30 Jul 2023 13:11:43 +0300 Subject: [PATCH 51/71] =?UTF-8?q?HW07=20IML=20=D0=B4=D0=B8=D0=B0=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=D0=BC=D0=B0=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0,=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D1=81=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=BE=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D1=81=D0=BF=D0=BE=D1=81=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20ResumeTestData=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BD.=20=D0=98=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=84=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index 19d454f..298268c 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -16,7 +16,7 @@ private ResumeTestData() { } public static void fillResumeTestData() { - resume = new Resume("Grigoriy Kislicyn"); + resume = new Resume("Grigoriy Kislin"); resume.addContact(MOBILE, "+7(921) 855-0482 "); resume.addContact(SKYPE, "skype:grigory.kislin"); resume.addContact(MAIL, "gkislin@yandex.ru"); From 6fa48df5641ff185d12b6dc146b3edea71c26efc Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:29:09 +0300 Subject: [PATCH 52/71] =?UTF-8?q?HW07=20Period=20=D0=B2=D1=8B=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=D0=B5=D0=BD=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81,=20?= =?UTF-8?q?=D0=B4=D1=80=D1=83=D0=B3=D0=B8=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D1=8B=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 6 +- src/com/learnjava/model/Experience.java | 61 ------------------- .../learnjava/model/ExperienceSection.java | 38 ------------ src/com/learnjava/model/Organization.java | 56 +++++++++++++++++ .../learnjava/model/OrganizationSection.java | 38 ++++++++++++ src/com/learnjava/model/Period.java | 17 ++++++ 6 files changed, 114 insertions(+), 102 deletions(-) delete mode 100644 src/com/learnjava/model/Experience.java delete mode 100644 src/com/learnjava/model/ExperienceSection.java create mode 100644 src/com/learnjava/model/Organization.java create mode 100644 src/com/learnjava/model/OrganizationSection.java create mode 100644 src/com/learnjava/model/Period.java diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index 298268c..d5c243c 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -22,9 +22,9 @@ public static void fillResumeTestData() { resume.addContact(MAIL, "gkislin@yandex.ru"); resume.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); resume.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); - resume.addSection(SectionType.EXPERIENCE, new ExperienceSection(Arrays.asList( - new Experience("Java Online Projects", "https://javaops.ru/", LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок.") - , new Experience("Wrike", "https://www.wrike.com/aa/", LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))); + resume.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( + new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))) + , new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); } diff --git a/src/com/learnjava/model/Experience.java b/src/com/learnjava/model/Experience.java deleted file mode 100644 index 1819cb2..0000000 --- a/src/com/learnjava/model/Experience.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.learnjava.model; - -import java.time.LocalDate; -import java.util.Objects; - -public class Experience { - private final String Organization; - private final Link homePage; - private final LocalDate startDate; - private final LocalDate endDate; - private final String title; - private final String description; - - public Experience(String name, String url, LocalDate startDate, LocalDate endDate, String title, String description) { - this.Organization = name; - this.homePage = new Link(name, url); - this.startDate = startDate; - this.endDate = endDate; - this.title = title; - this.description = description; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Experience that = (Experience) o; - - if (!Organization.equals(that.Organization)) return false; - if (!homePage.equals(that.homePage)) return false; - if (!startDate.equals(that.startDate)) return false; - if (!endDate.equals(that.endDate)) return false; - if (!title.equals(that.title)) return false; - return Objects.equals(description, that.description); - - } - - @Override - public int hashCode() { - int result = homePage.hashCode(); - result = 31 * result + Organization.hashCode(); - result = 31 * result + startDate.hashCode(); - result = 31 * result + endDate.hashCode(); - result = 31 * result + title.hashCode(); - result = 31 * result + (description != null ? description.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return "\n Organization{" + - Organization + - ", homePage=" + homePage + - ", startDate=" + startDate + - ", endDate=" + endDate + - ", title='" + title + '\'' + - ", description='" + description + '\'' + - "}"; - } -} \ No newline at end of file diff --git a/src/com/learnjava/model/ExperienceSection.java b/src/com/learnjava/model/ExperienceSection.java deleted file mode 100644 index 08ca65b..0000000 --- a/src/com/learnjava/model/ExperienceSection.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.learnjava.model; - -import java.util.List; -import java.util.Objects; - -public class ExperienceSection extends Section { - private final List Experiences; - - public ExperienceSection(List Experiences) { - Objects.requireNonNull(Experiences, "Experiences must not be null"); - this.Experiences = Experiences; - } - - public List getExperiences() { - return Experiences; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ExperienceSection that = (ExperienceSection) o; - - return Experiences.equals(that.Experiences); - - } - - @Override - public int hashCode() { - return Experiences.hashCode(); - } - - @Override - public String toString() { - return Experiences.toString(); - } -} \ No newline at end of file diff --git a/src/com/learnjava/model/Organization.java b/src/com/learnjava/model/Organization.java new file mode 100644 index 0000000..d8d8f1d --- /dev/null +++ b/src/com/learnjava/model/Organization.java @@ -0,0 +1,56 @@ +package com.learnjava.model; + +import java.util.List; + +public class Organization { + private List periods; + private final String Organization; + private final Link homePage; + + public Organization(String name, String url, List periods) { + Organization = name; + homePage = new Link(name, url); + this.periods = periods; + } + + public List getPeriods() { + return periods; + } + + public void setPreiods(List periods) { + this.periods = periods; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + com.learnjava.model.Organization that = (com.learnjava.model.Organization) o; + + if (!Organization.equals(that.Organization)) return false; + return homePage.equals(that.homePage); + } + + @Override + public int hashCode() { + int result = homePage.hashCode(); + result = 31 * result + Organization.hashCode(); + result = 31 * result + homePage.hashCode(); + return result; + } + + @Override + public String toString() { + String periodText = "\n Organization{" + Organization + ", homePage=" + homePage; + periods.forEach(period -> periodText.concat( + ", startDate=" + period.startDate + + ", endDate=" + period.endDate + + ", title='" + period.title + "'" + + ", description='" + period.description + "'\n" + ) + ); + + return periodText; + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/OrganizationSection.java b/src/com/learnjava/model/OrganizationSection.java new file mode 100644 index 0000000..704e89f --- /dev/null +++ b/src/com/learnjava/model/OrganizationSection.java @@ -0,0 +1,38 @@ +package com.learnjava.model; + +import java.util.List; +import java.util.Objects; + +public class OrganizationSection extends Section { + private final List organizations; + + public OrganizationSection(List organizations) { + Objects.requireNonNull(organizations, "Experiences must not be null"); + this.organizations = organizations; + } + + public List getExperiences() { + return organizations; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + OrganizationSection that = (OrganizationSection) o; + + return organizations.equals(that.organizations); + + } + + @Override + public int hashCode() { + return organizations.hashCode(); + } + + @Override + public String toString() { + return organizations.toString(); + } +} \ No newline at end of file diff --git a/src/com/learnjava/model/Period.java b/src/com/learnjava/model/Period.java new file mode 100644 index 0000000..f379c68 --- /dev/null +++ b/src/com/learnjava/model/Period.java @@ -0,0 +1,17 @@ +package com.learnjava.model; + +import java.time.LocalDate; + +public class Period { + public LocalDate startDate; + public LocalDate endDate; + + public String title; + public String description; + public Period(LocalDate startDate,LocalDate endDate,String title,String description){ + this.startDate = startDate ; + this.endDate = endDate ; + this.title = title ; + this.description = description ; + } +} From c58d48079b450c2c21fd27c0fc18191381cb6beb Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Fri, 4 Aug 2023 11:32:22 +0300 Subject: [PATCH 53/71] =?UTF-8?q?HW08=20=D1=81=D0=BE=D1=85=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B0=20=D0=B2=D1=81?= =?UTF-8?q?=D1=8F=D0=BA=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 4 +- .../learnjava/exception/StorageException.java | 5 + .../storage/AbstractFileStorage.java | 106 ++++++++++++++++++ .../learnjava/storage/AbstractStorage.java | 30 ++--- 4 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 src/com/learnjava/storage/AbstractFileStorage.java diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index d5c243c..c234227 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -22,9 +22,7 @@ public static void fillResumeTestData() { resume.addContact(MAIL, "gkislin@yandex.ru"); resume.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); resume.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); - resume.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( - new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))) - , new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); + resume.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList(new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); } diff --git a/src/com/learnjava/exception/StorageException.java b/src/com/learnjava/exception/StorageException.java index f058bbf..b108659 100644 --- a/src/com/learnjava/exception/StorageException.java +++ b/src/com/learnjava/exception/StorageException.java @@ -8,6 +8,11 @@ public StorageException(String message, String uuid) { this.uuid = uuid; } + public StorageException(String message, String uuid, Exception e) { + super(message, e); + this.uuid = uuid; + } + public String getUuid() { return uuid; } diff --git a/src/com/learnjava/storage/AbstractFileStorage.java b/src/com/learnjava/storage/AbstractFileStorage.java new file mode 100644 index 0000000..29725df --- /dev/null +++ b/src/com/learnjava/storage/AbstractFileStorage.java @@ -0,0 +1,106 @@ +package com.learnjava.storage; + +import com.learnjava.exception.*; +import com.learnjava.model.*; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public abstract class AbstractFileStorage extends AbstractStorage { + private File directory; + + protected AbstractFileStorage(File directory) { + Objects.requireNonNull(directory, "directory must not be null"); + if (!directory.isDirectory()) { + throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); + } + if (!directory.canRead() || !directory.canWrite()) { + throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); + } + this.directory = directory; + } + + @Override + public void clear() { + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + doDelete(file); + } + } + } + + @Override + public int size() { + String[] list = directory.list(); + if (list == null) { + throw new StorageException("Directory read error", null); + } + return list.length; + } + + @Override + protected File getSearchKey(String uuid) { + return new File(directory, uuid); + } + + @Override + protected void doUpdate(Resume r, File file) { + try { + doWrite(r, file); + } catch (IOException e) { + throw new StorageException("File write error", r.getUuid(), e); + } + } + + @Override + protected boolean isExist(File file) { + return file.exists(); + } + + @Override + protected void doSave(Resume r, File file) { + try { + file.createNewFile(); + } catch (IOException e) { + throw new StorageException("Couldn't create file " + file.getAbsolutePath(), file.getName(), e); + } + doUpdate(r, file); + } + + protected abstract void doWrite(Resume r, File file) throws IOException; + + protected abstract Resume doRead(File file) throws IOException; + + @Override + protected Resume doGet(File file) { + try { + return doRead(file); + } catch (IOException e) { + throw new StorageException("File read error", file.getName(), e); + } + } + + @Override + protected void doDelete(File file) { + if (!file.delete()) { + throw new StorageException("File delete error", file.getName()); + } + } + + @Override + protected List doCopyAll() { + File[] files = directory.listFiles(); + if (files == null) { + throw new StorageException("Directory read error", null); + } + List list = new ArrayList<>(files.length); + for (File file : files) { + list.add(doGet(file)); + } + return list; + } +} \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractStorage.java b/src/com/learnjava/storage/AbstractStorage.java index 655681c..2a49ce7 100644 --- a/src/com/learnjava/storage/AbstractStorage.java +++ b/src/com/learnjava/storage/AbstractStorage.java @@ -7,51 +7,51 @@ import java.util.Comparator; import java.util.List; -public abstract class AbstractStorage implements Storage { - protected abstract Object getSearchKey(String uuid); +public abstract class AbstractStorage implements Storage { + protected abstract SK getSearchKey(String uuid); - protected abstract void doUpdate(Resume r, Object searchKey); + protected abstract void doUpdate(Resume r, SK searchKey); - protected abstract boolean isExist(Object searchKey); + protected abstract boolean isExist(SK searchKey); - protected abstract void doSave(Resume r, Object searchKey); + protected abstract void doSave(Resume r, SK searchKey); - protected abstract Resume doGet(Object searchKey); + protected abstract Resume doGet(SK searchKey); - protected abstract void doDelete(Object searchKey); + protected abstract void doDelete(SK searchKey); protected abstract List doCopyAll(); private static final Comparator RESUME_COMPARATOR = Comparator.comparing(Resume::getUuid); public void update(Resume r) { - Object searchKey = getExistedSearchKey(r.getUuid()); + SK searchKey = getExistedSearchKey(r.getUuid()); doUpdate(r, searchKey); } public void save(Resume r) { - Object searchKey = getNotExistedSearchKey(r.getUuid()); + SK searchKey = getNotExistedSearchKey(r.getUuid()); doSave(r, searchKey); } public void delete(String uuid) { - Object searchKey = getExistedSearchKey(uuid); + SK searchKey = getExistedSearchKey(uuid); doDelete(searchKey); } public Resume get(String uuid) { - Object searchKey = getExistedSearchKey(uuid); + SK searchKey = getExistedSearchKey(uuid); return doGet(searchKey); } - private Object getExistedSearchKey(String uuid) { - Object searchKey = getSearchKey(uuid); + private SK getExistedSearchKey(String uuid) { + SK searchKey = getSearchKey(uuid); if (!isExist(searchKey)) { throw new NotExistStorageException(uuid); } return searchKey; } - private Object getNotExistedSearchKey(String uuid) { - Object searchKey = getSearchKey(uuid); + private SK getNotExistedSearchKey(String uuid) { + SK searchKey = getSearchKey(uuid); if (isExist(searchKey)) { throw new ExistStorageException(uuid); } From 9a56ce8a4749d4f6a60c7d5cdb03fbe9e9ef93e7 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:42:30 +0300 Subject: [PATCH 54/71] =?UTF-8?q?HW08=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainFile.java | 56 +++++++++++++++++++ src/com/learnjava/MainTestArrayStorage.java | 2 +- src/com/learnjava/ResumeTestData.java | 27 ++++----- .../storage/AbstractStorageTest.java | 11 ++-- 4 files changed, 76 insertions(+), 20 deletions(-) create mode 100644 src/com/learnjava/MainFile.java diff --git a/src/com/learnjava/MainFile.java b/src/com/learnjava/MainFile.java new file mode 100644 index 0000000..44b31d4 --- /dev/null +++ b/src/com/learnjava/MainFile.java @@ -0,0 +1,56 @@ +package com.learnjava; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; + +public class MainFile { + public static void main(String[] args) { + String filePath = ".\\.gitignore"; + + File file = new File(filePath); + try { + System.out.println(file.getCanonicalPath()); + } catch (IOException e) { + throw new RuntimeException("Error", e); + } + + File dir = new File("./src/com/learnjava"); + System.out.println(dir.isDirectory()); + String[] list = dir.list(); + if (list != null) { + for (String name : list) { + System.out.println(name); + } + } + + try (FileInputStream fis = new FileInputStream(filePath)) { + System.out.println(fis.read()); + } catch (IOException e) { + throw new RuntimeException(e); + } + printDirectoryDeeply(dir,0); + } + + public static void printDirectoryDeeply(File dir, int deep) { + File[] files = dir.listFiles(); + int nextDeep = deep + 2; + char[] spaces = new char[deep]; + Arrays.fill(spaces, ' '); + + if (files != null) { + for (File file : files) { + if (file.isFile()) { + System.out.println("File: " + new String(spaces) + file.getName()); + } + } + for (File file : files) { + if (file.isDirectory()) { + System.out.println("Dir: " + new String(spaces) + file.getName()); + printDirectoryDeeply(file, nextDeep); + } + } + } + } +} diff --git a/src/com/learnjava/MainTestArrayStorage.java b/src/com/learnjava/MainTestArrayStorage.java index 8357c71..bb67944 100644 --- a/src/com/learnjava/MainTestArrayStorage.java +++ b/src/com/learnjava/MainTestArrayStorage.java @@ -34,7 +34,7 @@ public static void main(String[] args) { static void printAll() { System.out.println("\nGet All"); - for (Resume r : ARRAY_STORAGE.getAllSorted()) { + for (Object r : ARRAY_STORAGE.getAllSorted()) { System.out.println(r); } } diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index c234227..58048eb 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -4,6 +4,7 @@ import java.time.LocalDate; import java.util.Arrays; +import java.util.UUID; import static com.learnjava.model.ContactType.*; import static com.learnjava.model.SectionType.*; @@ -15,17 +16,6 @@ public class ResumeTestData { private ResumeTestData() { } - public static void fillResumeTestData() { - resume = new Resume("Grigoriy Kislin"); - resume.addContact(MOBILE, "+7(921) 855-0482 "); - resume.addContact(SKYPE, "skype:grigory.kislin"); - resume.addContact(MAIL, "gkislin@yandex.ru"); - resume.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); - resume.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); - resume.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList(new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); - } - - public static void printResumeTestData() { System.out.println("uuid and full name: " + resume.toString()); System.out.println(MOBILE.getTitle() + " : " + resume.getContact(MOBILE)); @@ -36,8 +26,19 @@ public static void printResumeTestData() { System.out.println(EXPERIENCE.getTitle() + " : " + resume.getSection(EXPERIENCE).toString()); } - public static void main(String[] args) { - fillResumeTestData(); + public static Resume fillResumeTestData(String uuid, String fullname) { + Resume resumeWData = new Resume(uuid, fullname); + resumeWData.addContact(MOBILE, "+7(921) 855-0482 "); + resumeWData.addContact(SKYPE, "skype:grigory.kislin"); + resumeWData.addContact(MAIL, "gkislin@yandex.ru"); + resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); + resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); + resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList(new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); + return resumeWData; + } + + public void main(String[] args) { + resume = fillResumeTestData(UUID.randomUUID().toString(), "Grigoriy Kislin"); printResumeTestData(); } } \ No newline at end of file diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 628bd4f..8e8ec08 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -14,26 +14,25 @@ public abstract class AbstractStorageTest { protected Storage emptyStorage; private static final String UUID_1 = "uuid1"; - private static final Resume RESUME_1 = new Resume(UUID_1, "Ivanov"); + private static final Resume RESUME_1 = fillResumeTestData(UUID_1, "Ivanov"); private static final String UUID_2 = "uuid2"; - private static final Resume RESUME_2 = new Resume(UUID_2,"Petrov"); + private static final Resume RESUME_2 = fillResumeTestData(UUID_2,"Petrov"); private static final String UUID_3 = "uuid3"; - private static final Resume RESUME_3 = new Resume(UUID_3,"Sidorov"); + private static final Resume RESUME_3 = fillResumeTestData(UUID_3,"Sidorov"); private static final String UUID_4 = "extra_uuid"; - private static final Resume RESUME_4 = new Resume(UUID_4,"Kuznetcov"); + private static final Resume RESUME_4 = fillResumeTestData(UUID_4,"Kuznetcov"); private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; - private static final Resume RESUME_5 = new Resume(UUID_NOT_EXIST,"Gzhegosh"); + private static final Resume RESUME_5 = fillResumeTestData(UUID_NOT_EXIST,"Gzhegosh"); protected AbstractStorageTest(Storage storage, Storage emptyStorage) { this.storage = storage; this.emptyStorage = emptyStorage; } - @BeforeEach public void beforeEach() { if (storage != null) { From 5586b8fd36ef54a17fa7926db05753ecc60083b4 Mon Sep 17 00:00:00 2001 From: Pavel Teryoshin <116794811+pteryo@users.noreply.github.com> Date: Fri, 4 Aug 2023 15:48:41 +0300 Subject: [PATCH 55/71] =?UTF-8?q?HW08=20=D0=94=D0=97=20=D1=81=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 4 ++++ test/com/learnjava/storage/AbstractStorageTest.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index 58048eb..19eaac2 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -31,6 +31,10 @@ public static Resume fillResumeTestData(String uuid, String fullname) { resumeWData.addContact(MOBILE, "+7(921) 855-0482 "); resumeWData.addContact(SKYPE, "skype:grigory.kislin"); resumeWData.addContact(MAIL, "gkislin@yandex.ru"); + resumeWData.addContact(LINKEDIN, "linkedin.com/in/gkislin"); + resumeWData.addContact(GITHUB, "github.com/gkislin"); + resumeWData.addContact(STATCKOVERFLOW, "stackoverflow.com/users/548473"); + resumeWData.addContact(HOME_PAGE, "gkislin.ru/"); resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList(new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 8e8ec08..47beea0 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -9,6 +9,8 @@ import java.util.Arrays; import java.util.List; +import static com.learnjava.ResumeTestData.fillResumeTestData; + public abstract class AbstractStorageTest { protected Storage storage; protected Storage emptyStorage; From 2f3447a65feffcb2ed82932c646297ae3b5834f5 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Sun, 6 Aug 2023 14:11:54 +0300 Subject: [PATCH 56/71] =?UTF-8?q?HW08=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=83=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 6 +++--- .../learnjava/storage/AbstractFileStorage.java | 15 +++++++++------ .../learnjava/storage/AbstractStorageTest.java | 12 ++++++------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index 19eaac2..bebd05f 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -26,8 +26,8 @@ public static void printResumeTestData() { System.out.println(EXPERIENCE.getTitle() + " : " + resume.getSection(EXPERIENCE).toString()); } - public static Resume fillResumeTestData(String uuid, String fullname) { - Resume resumeWData = new Resume(uuid, fullname); + public static Resume getFilledResume(String uuid, String fullName) { + Resume resumeWData = new Resume(uuid, fullName); resumeWData.addContact(MOBILE, "+7(921) 855-0482 "); resumeWData.addContact(SKYPE, "skype:grigory.kislin"); resumeWData.addContact(MAIL, "gkislin@yandex.ru"); @@ -42,7 +42,7 @@ public static Resume fillResumeTestData(String uuid, String fullname) { } public void main(String[] args) { - resume = fillResumeTestData(UUID.randomUUID().toString(), "Grigoriy Kislin"); + resume = getFilledResume(UUID.randomUUID().toString(), "Grigoriy Kislin"); printResumeTestData(); } } \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractFileStorage.java b/src/com/learnjava/storage/AbstractFileStorage.java index 29725df..bcb8545 100644 --- a/src/com/learnjava/storage/AbstractFileStorage.java +++ b/src/com/learnjava/storage/AbstractFileStorage.java @@ -10,7 +10,8 @@ import java.util.Objects; public abstract class AbstractFileStorage extends AbstractStorage { - private File directory; + private final File directory; + protected AbstractFileStorage(File directory) { Objects.requireNonNull(directory, "directory must not be null"); @@ -26,7 +27,9 @@ protected AbstractFileStorage(File directory) { @Override public void clear() { File[] files = directory.listFiles(); - if (files != null) { + if (files == null) { + throw new StorageException("Directory clear error", null); + } else { for (File file : files) { doDelete(file); } @@ -71,10 +74,6 @@ protected void doSave(Resume r, File file) { doUpdate(r, file); } - protected abstract void doWrite(Resume r, File file) throws IOException; - - protected abstract Resume doRead(File file) throws IOException; - @Override protected Resume doGet(File file) { try { @@ -103,4 +102,8 @@ protected List doCopyAll() { } return list; } + + protected abstract void doWrite(Resume r, File file) throws IOException; + + protected abstract Resume doRead(File file) throws IOException; } \ No newline at end of file diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 47beea0..6169014 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -9,26 +9,26 @@ import java.util.Arrays; import java.util.List; -import static com.learnjava.ResumeTestData.fillResumeTestData; +import static com.learnjava.ResumeTestData.getFilledResume; public abstract class AbstractStorageTest { protected Storage storage; protected Storage emptyStorage; private static final String UUID_1 = "uuid1"; - private static final Resume RESUME_1 = fillResumeTestData(UUID_1, "Ivanov"); + private static final Resume RESUME_1 = getFilledResume(UUID_1, "Ivanov"); private static final String UUID_2 = "uuid2"; - private static final Resume RESUME_2 = fillResumeTestData(UUID_2,"Petrov"); + private static final Resume RESUME_2 = getFilledResume(UUID_2,"Petrov"); private static final String UUID_3 = "uuid3"; - private static final Resume RESUME_3 = fillResumeTestData(UUID_3,"Sidorov"); + private static final Resume RESUME_3 = getFilledResume(UUID_3,"Sidorov"); private static final String UUID_4 = "extra_uuid"; - private static final Resume RESUME_4 = fillResumeTestData(UUID_4,"Kuznetcov"); + private static final Resume RESUME_4 = getFilledResume(UUID_4,"Kuznetcov"); private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; - private static final Resume RESUME_5 = fillResumeTestData(UUID_NOT_EXIST,"Gzhegosh"); + private static final Resume RESUME_5 = getFilledResume(UUID_NOT_EXIST,"Gzhegosh"); protected AbstractStorageTest(Storage storage, Storage emptyStorage) { this.storage = storage; From dfac9ef7dd5d4e8c96e22f6fd7843f9b3f7caeae Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Sun, 6 Aug 2023 19:15:21 +0300 Subject: [PATCH 57/71] =?UTF-8?q?HW09=20=D1=80=D0=B5=D0=BA=D1=83=D1=80?= =?UTF-8?q?=D1=81=D0=B8=D0=B2=D0=BD=D1=8B=D0=B9=20=D0=BE=D0=B1=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=20=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B5=D0=B5=20(=D0=B2=20HW08),=20PathStorage,=20FileStor?= =?UTF-8?q?age=20+=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BA=20=D0=BD?= =?UTF-8?q?=D0=B8=D0=BC=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D1=8B=20=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B9=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../learnjava/exception/StorageException.java | 8 +- src/com/learnjava/model/Link.java | 3 +- src/com/learnjava/model/Organization.java | 3 +- src/com/learnjava/model/Period.java | 3 +- src/com/learnjava/model/Resume.java | 7 +- src/com/learnjava/model/Section.java | 4 +- .../serializer/ObjectStreamSerializer.java | 24 ++++ .../serializer/StreamSerializer.java | 12 ++ ...tractFileStorage.java => FileStorage.java} | 33 +++--- src/com/learnjava/storage/PathStorage.java | 105 ++++++++++++++++++ .../storage/AbstractStorageTest.java | 6 +- .../learnjava/storage/FileStorageTest.java | 10 ++ .../learnjava/storage/PathStorageTest.java | 9 ++ .../learnjava/storage/everyStorageTest.java | 4 +- 14 files changed, 202 insertions(+), 29 deletions(-) create mode 100644 src/com/learnjava/serializer/ObjectStreamSerializer.java create mode 100644 src/com/learnjava/serializer/StreamSerializer.java rename src/com/learnjava/storage/{AbstractFileStorage.java => FileStorage.java} (75%) create mode 100644 src/com/learnjava/storage/PathStorage.java create mode 100644 test/com/learnjava/storage/FileStorageTest.java create mode 100644 test/com/learnjava/storage/PathStorageTest.java diff --git a/src/com/learnjava/exception/StorageException.java b/src/com/learnjava/exception/StorageException.java index b108659..61f5040 100644 --- a/src/com/learnjava/exception/StorageException.java +++ b/src/com/learnjava/exception/StorageException.java @@ -3,11 +3,17 @@ public class StorageException extends RuntimeException { private final String uuid; + public StorageException(String message) { + this(message, null, null); + } + public StorageException(String message, String uuid) { super(message); this.uuid = uuid; } - + public StorageException(String message, Exception e) { + this(message, null, e); + } public StorageException(String message, String uuid, Exception e) { super(message, e); this.uuid = uuid; diff --git a/src/com/learnjava/model/Link.java b/src/com/learnjava/model/Link.java index 4c19132..521fc17 100644 --- a/src/com/learnjava/model/Link.java +++ b/src/com/learnjava/model/Link.java @@ -1,8 +1,9 @@ package com.learnjava.model; +import java.io.Serializable; import java.util.Objects; -public class Link { +public class Link implements Serializable { private final String name; private final String url; diff --git a/src/com/learnjava/model/Organization.java b/src/com/learnjava/model/Organization.java index d8d8f1d..2b632ea 100644 --- a/src/com/learnjava/model/Organization.java +++ b/src/com/learnjava/model/Organization.java @@ -1,8 +1,9 @@ package com.learnjava.model; +import java.io.Serializable; import java.util.List; -public class Organization { +public class Organization implements Serializable { private List periods; private final String Organization; private final Link homePage; diff --git a/src/com/learnjava/model/Period.java b/src/com/learnjava/model/Period.java index f379c68..be43267 100644 --- a/src/com/learnjava/model/Period.java +++ b/src/com/learnjava/model/Period.java @@ -1,8 +1,9 @@ package com.learnjava.model; +import java.io.Serializable; import java.time.LocalDate; -public class Period { +public class Period implements Serializable { public LocalDate startDate; public LocalDate endDate; diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index 5ddf613..8f79709 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -1,14 +1,15 @@ package com.learnjava.model; -import java.util.Objects; -import java.util.UUID; +import java.io.Serializable; import java.util.EnumMap; import java.util.Map; +import java.util.Objects; +import java.util.UUID; /** * ru.javawebinar.basejava.model.Resume class */ -public class Resume implements Comparable { +public class Resume implements Comparable, Serializable { // Unique identifier private final String uuid; diff --git a/src/com/learnjava/model/Section.java b/src/com/learnjava/model/Section.java index f2ea793..2323371 100644 --- a/src/com/learnjava/model/Section.java +++ b/src/com/learnjava/model/Section.java @@ -1,4 +1,6 @@ package com.learnjava.model; -abstract public class Section { +import java.io.Serializable; + +abstract public class Section implements Serializable { } diff --git a/src/com/learnjava/serializer/ObjectStreamSerializer.java b/src/com/learnjava/serializer/ObjectStreamSerializer.java new file mode 100644 index 0000000..f1b802f --- /dev/null +++ b/src/com/learnjava/serializer/ObjectStreamSerializer.java @@ -0,0 +1,24 @@ +package com.learnjava.serializer; + +import com.learnjava.exception.StorageException; +import com.learnjava.model.Resume; + +import java.io.*; +public class ObjectStreamSerializer implements StreamSerializer { + + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (ObjectOutputStream oos = new ObjectOutputStream(os)) { + oos.writeObject(r); + } + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (ObjectInputStream ois = new ObjectInputStream(is)) { + return (Resume) ois.readObject(); + } catch (ClassNotFoundException e) { + throw new StorageException("Error read resume", null, e); + } + } +} diff --git a/src/com/learnjava/serializer/StreamSerializer.java b/src/com/learnjava/serializer/StreamSerializer.java new file mode 100644 index 0000000..9ac1228 --- /dev/null +++ b/src/com/learnjava/serializer/StreamSerializer.java @@ -0,0 +1,12 @@ +package com.learnjava.serializer; + +import com.learnjava.model.Resume; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +public interface StreamSerializer { + void doWrite(Resume r, OutputStream os) throws IOException; + + Resume doRead(InputStream is) throws IOException; +} \ No newline at end of file diff --git a/src/com/learnjava/storage/AbstractFileStorage.java b/src/com/learnjava/storage/FileStorage.java similarity index 75% rename from src/com/learnjava/storage/AbstractFileStorage.java rename to src/com/learnjava/storage/FileStorage.java index bcb8545..a978fdd 100644 --- a/src/com/learnjava/storage/AbstractFileStorage.java +++ b/src/com/learnjava/storage/FileStorage.java @@ -1,20 +1,23 @@ package com.learnjava.storage; -import com.learnjava.exception.*; -import com.learnjava.model.*; +import com.learnjava.exception.StorageException; +import com.learnjava.model.Resume; +import com.learnjava.serializer.StreamSerializer; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; -public abstract class AbstractFileStorage extends AbstractStorage { - private final File directory; +public class FileStorage extends AbstractStorage { + private File directory; + private StreamSerializer streamSerializer; - protected AbstractFileStorage(File directory) { + protected FileStorage(File directory, StreamSerializer streamSerializer) { Objects.requireNonNull(directory, "directory must not be null"); + + this.streamSerializer = streamSerializer; if (!directory.isDirectory()) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); } @@ -27,9 +30,7 @@ protected AbstractFileStorage(File directory) { @Override public void clear() { File[] files = directory.listFiles(); - if (files == null) { - throw new StorageException("Directory clear error", null); - } else { + if (files != null) { for (File file : files) { doDelete(file); } @@ -40,7 +41,7 @@ public void clear() { public int size() { String[] list = directory.list(); if (list == null) { - throw new StorageException("Directory read error", null); + throw new StorageException("Directory read error"); } return list.length; } @@ -53,7 +54,7 @@ protected File getSearchKey(String uuid) { @Override protected void doUpdate(Resume r, File file) { try { - doWrite(r, file); + streamSerializer.doWrite(r, new BufferedOutputStream(new FileOutputStream(file))); } catch (IOException e) { throw new StorageException("File write error", r.getUuid(), e); } @@ -77,7 +78,7 @@ protected void doSave(Resume r, File file) { @Override protected Resume doGet(File file) { try { - return doRead(file); + return streamSerializer.doRead(new BufferedInputStream(new FileInputStream(file))); } catch (IOException e) { throw new StorageException("File read error", file.getName(), e); } @@ -94,7 +95,7 @@ protected void doDelete(File file) { protected List doCopyAll() { File[] files = directory.listFiles(); if (files == null) { - throw new StorageException("Directory read error", null); + throw new StorageException("Directory read error"); } List list = new ArrayList<>(files.length); for (File file : files) { @@ -102,8 +103,4 @@ protected List doCopyAll() { } return list; } - - protected abstract void doWrite(Resume r, File file) throws IOException; - - protected abstract Resume doRead(File file) throws IOException; } \ No newline at end of file diff --git a/src/com/learnjava/storage/PathStorage.java b/src/com/learnjava/storage/PathStorage.java new file mode 100644 index 0000000..01e0347 --- /dev/null +++ b/src/com/learnjava/storage/PathStorage.java @@ -0,0 +1,105 @@ +package com.learnjava.storage; + +import com.learnjava.exception.StorageException; +import com.learnjava.model.Resume; +import com.learnjava.serializer.StreamSerializer; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class PathStorage extends AbstractStorage { + private final Path directory; + private final StreamSerializer streamSerializer; + + protected PathStorage(String dir, StreamSerializer streamSerializer) { + Objects.requireNonNull(dir, "directory must not be null"); + + this.streamSerializer = streamSerializer; + directory = Paths.get(dir); + if (!Files.isDirectory(directory) || !Files.isWritable(directory)) { + throw new IllegalArgumentException(dir + " is not directory or is not writable"); + } + } + + @Override + public void clear() { + getFilesList().forEach(this::doDelete); + } + + @Override + public int size() { + return (int) getFilesList().count(); + } + + @Override + protected Path getSearchKey(String uuid) { + return directory.resolve(uuid); + } + + @Override + protected void doUpdate(Resume r, Path path) { + try { + streamSerializer.doWrite(r, new BufferedOutputStream(Files.newOutputStream(path))); + } catch (IOException e) { + throw new StorageException("Path write error", r.getUuid(), e); + } + } + + @Override + protected boolean isExist(Path path) { + return Files.isRegularFile(path); + } + + @Override + protected void doSave(Resume r, Path path) { + try { + Files.createFile(path); + } catch (IOException e) { + throw new StorageException("Couldn't create path " + path, getFileName(path), e); + } + doUpdate(r, path); + } + + @Override + protected Resume doGet(Path path) { + try { + return streamSerializer.doRead(new BufferedInputStream(Files.newInputStream(path))); + } catch (IOException e) { + throw new StorageException("Path read error", getFileName(path), e); + } + } + + @Override + protected void doDelete(Path path) { + try { + Files.delete(path); + } catch (IOException e) { + throw new StorageException("Path delete error", getFileName(path), e); + } + } + + @Override + protected List doCopyAll() { + return getFilesList().map(this::doGet).collect(Collectors.toList()); + } + + private String getFileName(Path path) { + return path.getFileName().toString(); + } + + private Stream getFilesList() { + try { + return Files.list(directory); + } catch (IOException e) { + throw new StorageException("Directory read error", e); + } + } +} \ No newline at end of file diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 6169014..2cb284d 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.io.File; import java.util.Arrays; import java.util.List; @@ -14,7 +15,8 @@ public abstract class AbstractStorageTest { protected Storage storage; protected Storage emptyStorage; - + protected static final File STORAGE_DIR = new File("D:\\YandexDisk\\_java_learn\\storage_files\\full"); + protected static final File STORAGE_DIR_EMPTY = new File("D:\\YandexDisk\\_java_learn\\storage_files\\empty"); private static final String UUID_1 = "uuid1"; private static final Resume RESUME_1 = getFilledResume(UUID_1, "Ivanov"); @@ -70,7 +72,7 @@ void clear() { void update() { Resume newResume = new Resume(UUID_1,"Ivanov"); storage.update(newResume); - Assertions.assertSame(newResume, storage.get(UUID_1)); + Assertions.assertTrue(newResume.equals(storage.get(UUID_1))); } @Test diff --git a/test/com/learnjava/storage/FileStorageTest.java b/test/com/learnjava/storage/FileStorageTest.java new file mode 100644 index 0000000..972a8a6 --- /dev/null +++ b/test/com/learnjava/storage/FileStorageTest.java @@ -0,0 +1,10 @@ +package com.learnjava.storage; + +import com.learnjava.serializer.ObjectStreamSerializer; + +public class FileStorageTest extends AbstractStorageTest { + + public FileStorageTest() { + super(new FileStorage(STORAGE_DIR, new ObjectStreamSerializer()), (new FileStorage(STORAGE_DIR_EMPTY, new ObjectStreamSerializer()))); + } +} \ No newline at end of file diff --git a/test/com/learnjava/storage/PathStorageTest.java b/test/com/learnjava/storage/PathStorageTest.java new file mode 100644 index 0000000..669e03d --- /dev/null +++ b/test/com/learnjava/storage/PathStorageTest.java @@ -0,0 +1,9 @@ +package com.learnjava.storage; + +import com.learnjava.serializer.ObjectStreamSerializer; + +public class PathStorageTest extends AbstractStorageTest { + public PathStorageTest() { + super(new PathStorage(STORAGE_DIR.getAbsolutePath(), new ObjectStreamSerializer()), (new PathStorage(STORAGE_DIR_EMPTY.getAbsolutePath(), new ObjectStreamSerializer()))); + } +} diff --git a/test/com/learnjava/storage/everyStorageTest.java b/test/com/learnjava/storage/everyStorageTest.java index 8006444..3bddaf9 100644 --- a/test/com/learnjava/storage/everyStorageTest.java +++ b/test/com/learnjava/storage/everyStorageTest.java @@ -9,7 +9,9 @@ SortedArrayStorageTest.class, ListStorageTest.class, MapStorageTest.class, - MapUUIDStorageTest.class + MapUUIDStorageTest.class, + FileStorageTest.class, + PathStorageTest.class }) public class everyStorageTest { From fc66a988334fd719257ba6aa58c1f70a26cae34a Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Mon, 7 Aug 2023 11:25:13 +0300 Subject: [PATCH 58/71] =?UTF-8?q?HW09=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainFile.java | 6 ++-- src/com/learnjava/storage/FileStorage.java | 30 ++++++++++--------- src/com/learnjava/storage/PathStorage.java | 2 +- .../serializer/ObjectStreamSerializer.java | 2 +- .../serializer/StreamSerializer.java | 2 +- .../storage/AbstractStorageTest.java | 23 ++++++-------- .../learnjava/storage/ArrayStorageTest.java | 2 -- .../learnjava/storage/FileStorageTest.java | 2 +- .../learnjava/storage/PathStorageTest.java | 6 ++-- .../storage/SortedArrayStorageTest.java | 2 -- 10 files changed, 35 insertions(+), 42 deletions(-) rename src/com/learnjava/{ => storage}/serializer/ObjectStreamSerializer.java (94%) rename src/com/learnjava/{ => storage}/serializer/StreamSerializer.java (86%) diff --git a/src/com/learnjava/MainFile.java b/src/com/learnjava/MainFile.java index 44b31d4..38aa0ad 100644 --- a/src/com/learnjava/MainFile.java +++ b/src/com/learnjava/MainFile.java @@ -16,7 +16,7 @@ public static void main(String[] args) { throw new RuntimeException("Error", e); } - File dir = new File("./src/com/learnjava"); + File dir = new File("./src"); System.out.println(dir.isDirectory()); String[] list = dir.list(); if (list != null) { @@ -42,12 +42,12 @@ public static void printDirectoryDeeply(File dir, int deep) { if (files != null) { for (File file : files) { if (file.isFile()) { - System.out.println("File: " + new String(spaces) + file.getName()); + System.out.println("File: " + new String(spaces) + file.getName()); } } for (File file : files) { if (file.isDirectory()) { - System.out.println("Dir: " + new String(spaces) + file.getName()); + System.out.println("Dir: " + new String(spaces) + file.getName()); printDirectoryDeeply(file, nextDeep); } } diff --git a/src/com/learnjava/storage/FileStorage.java b/src/com/learnjava/storage/FileStorage.java index a978fdd..a4c787c 100644 --- a/src/com/learnjava/storage/FileStorage.java +++ b/src/com/learnjava/storage/FileStorage.java @@ -2,7 +2,7 @@ import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; -import com.learnjava.serializer.StreamSerializer; +import com.learnjava.storage.serializer.StreamSerializer; import java.io.*; import java.util.ArrayList; @@ -10,9 +10,8 @@ import java.util.Objects; public class FileStorage extends AbstractStorage { - private File directory; - - private StreamSerializer streamSerializer; + private final File directory; + private final StreamSerializer streamSerializer; protected FileStorage(File directory, StreamSerializer streamSerializer) { Objects.requireNonNull(directory, "directory must not be null"); @@ -29,7 +28,7 @@ protected FileStorage(File directory, StreamSerializer streamSerializer) { @Override public void clear() { - File[] files = directory.listFiles(); + File[] files = doGetFiles(); if (files != null) { for (File file : files) { doDelete(file); @@ -39,11 +38,7 @@ public void clear() { @Override public int size() { - String[] list = directory.list(); - if (list == null) { - throw new StorageException("Directory read error"); - } - return list.length; + return doGetFiles().length; } @Override @@ -68,6 +63,7 @@ protected boolean isExist(File file) { @Override protected void doSave(Resume r, File file) { try { + //noinspection ResultOfMethodCallIgnored file.createNewFile(); } catch (IOException e) { throw new StorageException("Couldn't create file " + file.getAbsolutePath(), file.getName(), e); @@ -93,14 +89,20 @@ protected void doDelete(File file) { @Override protected List doCopyAll() { - File[] files = directory.listFiles(); - if (files == null) { - throw new StorageException("Directory read error"); - } + File[] files = doGetFiles(); List list = new ArrayList<>(files.length); for (File file : files) { list.add(doGet(file)); } return list; } + + protected File[] doGetFiles() { + File[] files = directory.listFiles(); + if (files == null) { + throw new StorageException("Directory read error"); + } else { + return files; + } + } } \ No newline at end of file diff --git a/src/com/learnjava/storage/PathStorage.java b/src/com/learnjava/storage/PathStorage.java index 01e0347..5eba898 100644 --- a/src/com/learnjava/storage/PathStorage.java +++ b/src/com/learnjava/storage/PathStorage.java @@ -2,7 +2,7 @@ import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; -import com.learnjava.serializer.StreamSerializer; +import com.learnjava.storage.serializer.StreamSerializer; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; diff --git a/src/com/learnjava/serializer/ObjectStreamSerializer.java b/src/com/learnjava/storage/serializer/ObjectStreamSerializer.java similarity index 94% rename from src/com/learnjava/serializer/ObjectStreamSerializer.java rename to src/com/learnjava/storage/serializer/ObjectStreamSerializer.java index f1b802f..af0ff8a 100644 --- a/src/com/learnjava/serializer/ObjectStreamSerializer.java +++ b/src/com/learnjava/storage/serializer/ObjectStreamSerializer.java @@ -1,4 +1,4 @@ -package com.learnjava.serializer; +package com.learnjava.storage.serializer; import com.learnjava.exception.StorageException; import com.learnjava.model.Resume; diff --git a/src/com/learnjava/serializer/StreamSerializer.java b/src/com/learnjava/storage/serializer/StreamSerializer.java similarity index 86% rename from src/com/learnjava/serializer/StreamSerializer.java rename to src/com/learnjava/storage/serializer/StreamSerializer.java index 9ac1228..f89c5be 100644 --- a/src/com/learnjava/serializer/StreamSerializer.java +++ b/src/com/learnjava/storage/serializer/StreamSerializer.java @@ -1,4 +1,4 @@ -package com.learnjava.serializer; +package com.learnjava.storage.serializer; import com.learnjava.model.Resume; diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 2cb284d..1594147 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -13,26 +13,22 @@ import static com.learnjava.ResumeTestData.getFilledResume; public abstract class AbstractStorageTest { - protected Storage storage; - protected Storage emptyStorage; protected static final File STORAGE_DIR = new File("D:\\YandexDisk\\_java_learn\\storage_files\\full"); protected static final File STORAGE_DIR_EMPTY = new File("D:\\YandexDisk\\_java_learn\\storage_files\\empty"); private static final String UUID_1 = "uuid1"; private static final Resume RESUME_1 = getFilledResume(UUID_1, "Ivanov"); - private static final String UUID_2 = "uuid2"; - private static final Resume RESUME_2 = getFilledResume(UUID_2,"Petrov"); - + private static final Resume RESUME_2 = getFilledResume(UUID_2, "Petrov"); private static final String UUID_3 = "uuid3"; - private static final Resume RESUME_3 = getFilledResume(UUID_3,"Sidorov"); - + private static final Resume RESUME_3 = getFilledResume(UUID_3, "Sidorov"); private static final String UUID_4 = "extra_uuid"; - private static final Resume RESUME_4 = getFilledResume(UUID_4,"Kuznetcov"); - + private static final Resume RESUME_4 = getFilledResume(UUID_4, "Kuznetcov"); private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; - private static final Resume RESUME_5 = getFilledResume(UUID_NOT_EXIST,"Gzhegosh"); + private static final Resume RESUME_5 = getFilledResume(UUID_NOT_EXIST, "Gzhegosh"); + protected Storage storage; + protected Storage emptyStorage; - protected AbstractStorageTest(Storage storage, Storage emptyStorage) { + protected AbstractStorageTest(Storage storage, Storage emptyStorage) { this.storage = storage; this.emptyStorage = emptyStorage; } @@ -55,7 +51,6 @@ private void assertSize(int size) { Assertions.assertEquals(size, storage.size()); } - @Test void size() { assertSize(3); @@ -70,9 +65,9 @@ void clear() { @Test void update() { - Resume newResume = new Resume(UUID_1,"Ivanov"); + Resume newResume = new Resume(UUID_1, "Ivanov"); storage.update(newResume); - Assertions.assertTrue(newResume.equals(storage.get(UUID_1))); + Assertions.assertEquals(newResume, storage.get(UUID_1)); } @Test diff --git a/test/com/learnjava/storage/ArrayStorageTest.java b/test/com/learnjava/storage/ArrayStorageTest.java index 4375ce6..55641fa 100644 --- a/test/com/learnjava/storage/ArrayStorageTest.java +++ b/test/com/learnjava/storage/ArrayStorageTest.java @@ -1,9 +1,7 @@ package com.learnjava.storage; public class ArrayStorageTest extends AbstractArrayStorageTest { - public ArrayStorageTest() { super(new ArrayStorage(), new ArrayStorage()); } - } \ No newline at end of file diff --git a/test/com/learnjava/storage/FileStorageTest.java b/test/com/learnjava/storage/FileStorageTest.java index 972a8a6..978c660 100644 --- a/test/com/learnjava/storage/FileStorageTest.java +++ b/test/com/learnjava/storage/FileStorageTest.java @@ -1,6 +1,6 @@ package com.learnjava.storage; -import com.learnjava.serializer.ObjectStreamSerializer; +import com.learnjava.storage.serializer.ObjectStreamSerializer; public class FileStorageTest extends AbstractStorageTest { diff --git a/test/com/learnjava/storage/PathStorageTest.java b/test/com/learnjava/storage/PathStorageTest.java index 669e03d..8b6a765 100644 --- a/test/com/learnjava/storage/PathStorageTest.java +++ b/test/com/learnjava/storage/PathStorageTest.java @@ -1,9 +1,9 @@ package com.learnjava.storage; -import com.learnjava.serializer.ObjectStreamSerializer; +import com.learnjava.storage.serializer.ObjectStreamSerializer; -public class PathStorageTest extends AbstractStorageTest { - public PathStorageTest() { +public class PathStorageTest extends AbstractStorageTest { + public PathStorageTest() { super(new PathStorage(STORAGE_DIR.getAbsolutePath(), new ObjectStreamSerializer()), (new PathStorage(STORAGE_DIR_EMPTY.getAbsolutePath(), new ObjectStreamSerializer()))); } } diff --git a/test/com/learnjava/storage/SortedArrayStorageTest.java b/test/com/learnjava/storage/SortedArrayStorageTest.java index 76cd9d2..1885171 100644 --- a/test/com/learnjava/storage/SortedArrayStorageTest.java +++ b/test/com/learnjava/storage/SortedArrayStorageTest.java @@ -1,9 +1,7 @@ package com.learnjava.storage; public class SortedArrayStorageTest extends AbstractArrayStorageTest { - public SortedArrayStorageTest() { super(new SortedArrayStorage(), new SortedArrayStorage()); } - } \ No newline at end of file From b79781964ddf81a727b634bdf24493b366365239 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:07:34 +0300 Subject: [PATCH 59/71] =?UTF-8?q?HW09=20=D0=B4=D1=80=D1=83=D0=B3=D0=BE?= =?UTF-8?q?=D0=B9=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=20=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B2=D0=B0=20=D0=BA=D0=B0=D1=82=D0=B0=D0=BB=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20=D0=B8=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/MainFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/learnjava/MainFile.java b/src/com/learnjava/MainFile.java index 38aa0ad..6869565 100644 --- a/src/com/learnjava/MainFile.java +++ b/src/com/learnjava/MainFile.java @@ -42,7 +42,7 @@ public static void printDirectoryDeeply(File dir, int deep) { if (files != null) { for (File file : files) { if (file.isFile()) { - System.out.println("File: " + new String(spaces) + file.getName()); + System.out.println("File: " + new String(spaces) + file.getName()); } } for (File file : files) { From f7dbdd638c67ed4d54730ed3db32b52d1425e5eb Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:46:43 +0300 Subject: [PATCH 60/71] =?UTF-8?q?HW10=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20DataStreamSerializer=20+=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 3 +- src/com/learnjava/model/Link.java | 7 +- src/com/learnjava/model/ListSection.java | 6 +- src/com/learnjava/model/Organization.java | 26 +++- .../learnjava/model/OrganizationSection.java | 16 ++- src/com/learnjava/model/Period.java | 61 ++++++++- src/com/learnjava/model/Resume.java | 37 +++++- src/com/learnjava/model/TextSection.java | 8 +- .../serializer/DataStreamSerializer.java | 116 ++++++++++++++++++ .../serializer/JsonStreamSerializer.java | 23 ++++ .../serializer/XmlStreamSerializer.java | 36 ++++++ src/com/learnjava/util/JsonParser.java | 26 ++++ .../learnjava/util/JsonSectionAdapter.java | 33 +++++ src/com/learnjava/util/LocalDateAdapter.java | 18 +++ .../learnjava/util/LocalDateTypeAdapter.java | 24 ++++ src/com/learnjava/util/XmlParser.java | 43 +++++++ .../storage/AbstractStorageTest.java | 2 +- .../learnjava/storage/FileStorageTest.java | 3 - .../storage/JsonPathStorageTest.java | 8 ++ .../learnjava/storage/PathStorageTest.java | 4 +- .../learnjava/storage/XmlPathStorageTest.java | 9 ++ .../learnjava/storage/everyStorageTest.java | 4 +- 22 files changed, 483 insertions(+), 30 deletions(-) create mode 100644 src/com/learnjava/storage/serializer/DataStreamSerializer.java create mode 100644 src/com/learnjava/storage/serializer/JsonStreamSerializer.java create mode 100644 src/com/learnjava/storage/serializer/XmlStreamSerializer.java create mode 100644 src/com/learnjava/util/JsonParser.java create mode 100644 src/com/learnjava/util/JsonSectionAdapter.java create mode 100644 src/com/learnjava/util/LocalDateAdapter.java create mode 100644 src/com/learnjava/util/LocalDateTypeAdapter.java create mode 100644 src/com/learnjava/util/XmlParser.java create mode 100644 test/com/learnjava/storage/JsonPathStorageTest.java create mode 100644 test/com/learnjava/storage/XmlPathStorageTest.java diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index bebd05f..41dbf02 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -37,7 +37,8 @@ public static Resume getFilledResume(String uuid, String fullName) { resumeWData.addContact(HOME_PAGE, "gkislin.ru/"); resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); - resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList(new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); + resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( + new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); return resumeWData; } diff --git a/src/com/learnjava/model/Link.java b/src/com/learnjava/model/Link.java index 521fc17..8809a3b 100644 --- a/src/com/learnjava/model/Link.java +++ b/src/com/learnjava/model/Link.java @@ -4,10 +4,13 @@ import java.util.Objects; public class Link implements Serializable { - private final String name; - private final String url; + private String name; + private String url; + @SuppressWarnings("unused") + public Link() { + } public Link(String name, String url) { this.name = name; this.url = url; diff --git a/src/com/learnjava/model/ListSection.java b/src/com/learnjava/model/ListSection.java index 3a19de0..551068d 100644 --- a/src/com/learnjava/model/ListSection.java +++ b/src/com/learnjava/model/ListSection.java @@ -4,7 +4,11 @@ import java.util.Objects; public class ListSection extends Section { - private final List items; + private List items; + + @SuppressWarnings("unused") + public ListSection() { + } public ListSection(List items) { Objects.requireNonNull(items, "items must not be null"); diff --git a/src/com/learnjava/model/Organization.java b/src/com/learnjava/model/Organization.java index 2b632ea..4dbed15 100644 --- a/src/com/learnjava/model/Organization.java +++ b/src/com/learnjava/model/Organization.java @@ -1,12 +1,19 @@ package com.learnjava.model; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import java.io.Serial; import java.io.Serializable; import java.util.List; +@XmlAccessorType(XmlAccessType.FIELD) public class Organization implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + private List periods; - private final String Organization; - private final Link homePage; + private String Organization; + private Link homePage; public Organization(String name, String url, List periods) { Organization = name; @@ -14,10 +21,14 @@ public Organization(String name, String url, List periods) { this.periods = periods; } + @SuppressWarnings("unused") + public Organization() { + } + @SuppressWarnings("unused") public List getPeriods() { return periods; } - + @SuppressWarnings("unused") public void setPreiods(List periods) { this.periods = periods; } @@ -44,6 +55,7 @@ public int hashCode() { @Override public String toString() { String periodText = "\n Organization{" + Organization + ", homePage=" + homePage; + //noinspection ResultOfMethodCallIgnored periods.forEach(period -> periodText.concat( ", startDate=" + period.startDate + ", endDate=" + period.endDate + @@ -54,4 +66,12 @@ public String toString() { return periodText; } + + public Link getHomePage() { + return homePage; + } + + public List getPositions() { + return periods; + } } \ No newline at end of file diff --git a/src/com/learnjava/model/OrganizationSection.java b/src/com/learnjava/model/OrganizationSection.java index 704e89f..2cec527 100644 --- a/src/com/learnjava/model/OrganizationSection.java +++ b/src/com/learnjava/model/OrganizationSection.java @@ -1,18 +1,19 @@ package com.learnjava.model; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; import java.util.List; import java.util.Objects; - +@XmlAccessorType(XmlAccessType.FIELD) public class OrganizationSection extends Section { - private final List organizations; + private List organizations; public OrganizationSection(List organizations) { Objects.requireNonNull(organizations, "Experiences must not be null"); this.organizations = organizations; } - - public List getExperiences() { - return organizations; + @SuppressWarnings("unused") + public OrganizationSection() { } @Override @@ -35,4 +36,9 @@ public int hashCode() { public String toString() { return organizations.toString(); } + + public List getOrganizations() { + return organizations; + } + } \ No newline at end of file diff --git a/src/com/learnjava/model/Period.java b/src/com/learnjava/model/Period.java index be43267..42bcc9d 100644 --- a/src/com/learnjava/model/Period.java +++ b/src/com/learnjava/model/Period.java @@ -1,18 +1,69 @@ package com.learnjava.model; +import com.learnjava.util.LocalDateAdapter; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.io.Serializable; import java.time.LocalDate; +import java.util.Objects; + +@XmlAccessorType(XmlAccessType.FIELD) public class Period implements Serializable { + @XmlJavaTypeAdapter(LocalDateAdapter.class) public LocalDate startDate; + @XmlJavaTypeAdapter(LocalDateAdapter.class) public LocalDate endDate; public String title; public String description; - public Period(LocalDate startDate,LocalDate endDate,String title,String description){ - this.startDate = startDate ; - this.endDate = endDate ; - this.title = title ; - this.description = description ; + + public Period(LocalDate startDate, LocalDate endDate, String title, String description) { + this.startDate = startDate; + this.endDate = endDate; + this.title = title; + this.description = description; + } + @SuppressWarnings("unused") + public Period() { + } + + public LocalDate getStartDate() { + return startDate; + } + + public LocalDate getEndDate() { + return endDate; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Period position = (Period) o; + return Objects.equals(startDate, position.startDate) && + Objects.equals(endDate, position.endDate) && + Objects.equals(title, position.title) && + Objects.equals(description, position.description); + } + + @Override + public int hashCode() { + return Objects.hash(startDate, endDate, title, description); + } + + @Override + public String toString() { + return "Position(" + startDate + ',' + endDate + ',' + title + ',' + description + ')'; } } diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index 8f79709..50949be 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -1,5 +1,10 @@ package com.learnjava.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serial; import java.io.Serializable; import java.util.EnumMap; import java.util.Map; @@ -9,24 +14,42 @@ /** * ru.javawebinar.basejava.model.Resume class */ -public class Resume implements Comparable, Serializable { +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class Resume implements Comparable, Serializable { + @Serial + private static final long serialVersionUID = 1L; // Unique identifier - private final String uuid; - private final String fullName; + private String uuid; + private String fullName; - private final Map contacts = new EnumMap<>(ContactType.class); - private final Map sections = new EnumMap<>(SectionType.class); + @SuppressWarnings("FieldMayBeFinal") + private Map contacts = new EnumMap<>(ContactType.class); + @SuppressWarnings("FieldMayBeFinal") + private Map sections = new EnumMap<>(SectionType.class); public Resume(String fullName) { this(UUID.randomUUID().toString(), fullName); } + public Resume() { + + } + public Resume(String uuid, String fullName) { this.uuid = uuid; this.fullName = fullName; } + public String getFullName() { + return fullName; + } + + public Map getContacts() { + return contacts; + } + public String getContact(ContactType type) { return contacts.get(type); } @@ -35,6 +58,10 @@ public Section getSection(SectionType type) { return sections.get(type); } + public Map getSections() { + return sections; + } + public void addContact(ContactType type, String value) { contacts.put(type, value); } diff --git a/src/com/learnjava/model/TextSection.java b/src/com/learnjava/model/TextSection.java index a388376..8143377 100644 --- a/src/com/learnjava/model/TextSection.java +++ b/src/com/learnjava/model/TextSection.java @@ -1,11 +1,17 @@ package com.learnjava.model; public class TextSection extends Section { - private final String content; + private String content; public TextSection(String content) { this.content = content; } + @SuppressWarnings("unused") + public TextSection() { + } + public String getContent() { + return content; + } @Override public String toString() { diff --git a/src/com/learnjava/storage/serializer/DataStreamSerializer.java b/src/com/learnjava/storage/serializer/DataStreamSerializer.java new file mode 100644 index 0000000..589e45c --- /dev/null +++ b/src/com/learnjava/storage/serializer/DataStreamSerializer.java @@ -0,0 +1,116 @@ +package com.learnjava.storage.serializer; + +import com.learnjava.model.*; + +import java.io.*; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import java.util.Collection; +import java.time.LocalDate; + +public class DataStreamSerializer implements StreamSerializer { + + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (DataOutputStream dos = new DataOutputStream(os)) { + dos.writeUTF(r.getUuid()); + dos.writeUTF(r.getFullName()); + Map contacts = r.getContacts(); + writeCollection(dos, contacts.entrySet(), entry -> { + dos.writeUTF(entry.getKey().name()); + dos.writeUTF(entry.getValue()); + }); + + writeCollection(dos, r.getSections().entrySet(), entry -> { + SectionType type = entry.getKey(); + Section section = entry.getValue(); + dos.writeUTF(type.name()); + switch (type) { + case PERSONAL, OBJECTIVE -> dos.writeUTF(((TextSection) section).getContent()); + case ACHIEVEMENT, QUALIFICATIONS -> + writeCollection(dos, ((ListSection) section).getItems(), dos::writeUTF); + case EXPERIENCE, EDUCATION -> + writeCollection(dos, ((OrganizationSection) section).getOrganizations(), org -> { + dos.writeUTF(org.getHomePage().getName()); + dos.writeUTF(org.getHomePage().getUrl()); + writeCollection(dos, org.getPositions(), position -> { + writeLocalDate(dos, position.getStartDate()); + writeLocalDate(dos, position.getEndDate()); + dos.writeUTF(position.getTitle()); + dos.writeUTF(position.getDescription()); + }); + }); + } + }); + } + } + + private void writeLocalDate(DataOutputStream dos, LocalDate ld) throws IOException { + dos.writeInt(ld.getYear()); + dos.writeInt(ld.getMonth().getValue()); + } + + private LocalDate readLocalDate(DataInputStream dis) throws IOException { + return LocalDate.of(dis.readInt(), dis.readInt(), 1); + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (DataInputStream dis = new DataInputStream(is)) { + String uuid = dis.readUTF(); + String fullName = dis.readUTF(); + Resume resume = new Resume(uuid, fullName); + readItems(dis, () -> resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF())); + readItems(dis, () -> { + SectionType sectionType = SectionType.valueOf(dis.readUTF()); + resume.addSection(sectionType, readSection(dis, sectionType)); + }); + return resume; + } + } + + private Section readSection(DataInputStream dis, SectionType sectionType) throws IOException { + return switch (sectionType) { + case PERSONAL, OBJECTIVE -> new TextSection(dis.readUTF()); + case ACHIEVEMENT, QUALIFICATIONS -> new ListSection(readList(dis, dis::readUTF)); + case EXPERIENCE, EDUCATION -> + new OrganizationSection(readList(dis, () -> new Organization(dis.readUTF(), dis.readUTF(), readList(dis, () -> new Period(readLocalDate(dis), readLocalDate(dis), dis.readUTF(), dis.readUTF()))))); + }; + } + + private List readList(DataInputStream dis, ElementReader reader) throws IOException { + int size = dis.readInt(); + List list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.add(reader.read()); + } + return list; + } + + private void readItems(DataInputStream dis, ElementProcessor processor) throws IOException { + int size = dis.readInt(); + for (int i = 0; i < size; i++) { + processor.process(); + } + } + + private void writeCollection(DataOutputStream dos, Collection collection, ElementWriter writer) throws IOException { + dos.writeInt(collection.size()); + for (T item : collection) { + writer.write(item); + } + } + + private interface ElementProcessor { + void process() throws IOException; + } + + private interface ElementReader { + T read() throws IOException; + } + + private interface ElementWriter { + void write(T t) throws IOException; + } +} \ No newline at end of file diff --git a/src/com/learnjava/storage/serializer/JsonStreamSerializer.java b/src/com/learnjava/storage/serializer/JsonStreamSerializer.java new file mode 100644 index 0000000..f74d0b6 --- /dev/null +++ b/src/com/learnjava/storage/serializer/JsonStreamSerializer.java @@ -0,0 +1,23 @@ +package com.learnjava.storage.serializer; + +import com.learnjava.model.Resume; +import com.learnjava.util.JsonParser; + +import java.io.*; +import java.nio.charset.StandardCharsets; +public class JsonStreamSerializer implements StreamSerializer { + + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (Writer writer = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { + JsonParser.write(r, writer); + } + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) { + return JsonParser.read(reader, Resume.class); + } + } +} \ No newline at end of file diff --git a/src/com/learnjava/storage/serializer/XmlStreamSerializer.java b/src/com/learnjava/storage/serializer/XmlStreamSerializer.java new file mode 100644 index 0000000..0d89aba --- /dev/null +++ b/src/com/learnjava/storage/serializer/XmlStreamSerializer.java @@ -0,0 +1,36 @@ +package com.learnjava.storage.serializer; + +import com.learnjava.util.XmlParser; +import com.learnjava.model.*; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class XmlStreamSerializer implements StreamSerializer { + private final XmlParser xmlParser; + + public XmlStreamSerializer() { + xmlParser = new XmlParser( + Resume.class, + Organization.class, + Link.class, + OrganizationSection.class, + TextSection.class, + ListSection.class, + Period.class); + } + + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (Writer w = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { + xmlParser.marshall(r, w); + } + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (Reader r = new InputStreamReader(is, StandardCharsets.UTF_8)) { + return xmlParser.unmarshall(r); + } + } +} \ No newline at end of file diff --git a/src/com/learnjava/util/JsonParser.java b/src/com/learnjava/util/JsonParser.java new file mode 100644 index 0000000..868c70b --- /dev/null +++ b/src/com/learnjava/util/JsonParser.java @@ -0,0 +1,26 @@ +package com.learnjava.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.learnjava.model.Section; + +import java.io.Reader; +import java.io.Writer; +import java.time.LocalDate; + +public class JsonParser { + + private final static Gson GSON = new GsonBuilder() + .registerTypeAdapter(Section.class, new JsonSectionAdapter()) + .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) + .create(); + + public static T read(Reader reader, Class clazz) { + return GSON.fromJson(reader, clazz); + } + + public static void write(T object, Writer writer) { + GSON.toJson(object, writer); + } + +} \ No newline at end of file diff --git a/src/com/learnjava/util/JsonSectionAdapter.java b/src/com/learnjava/util/JsonSectionAdapter.java new file mode 100644 index 0000000..db89ee7 --- /dev/null +++ b/src/com/learnjava/util/JsonSectionAdapter.java @@ -0,0 +1,33 @@ +package com.learnjava.util; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public class JsonSectionAdapter implements JsonSerializer, JsonDeserializer { + private static final String CLASSNAME = "CLASSNAME"; + private static final String INSTANCE = "INSTANCE"; + + @Override + public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME); + String className = prim.getAsString(); + + try { + Class clazz = Class.forName(className); + return context.deserialize(jsonObject.get(INSTANCE), clazz); + } catch (ClassNotFoundException e) { + throw new JsonParseException(e.getMessage()); + } + } + + @Override + public JsonElement serialize(T section, Type type, JsonSerializationContext context) { + JsonObject retValue = new JsonObject(); + retValue.addProperty(CLASSNAME, section.getClass().getName()); + JsonElement elem = context.serialize(section); + retValue.add(INSTANCE, elem); + return retValue; + } +} diff --git a/src/com/learnjava/util/LocalDateAdapter.java b/src/com/learnjava/util/LocalDateAdapter.java new file mode 100644 index 0000000..9430bfc --- /dev/null +++ b/src/com/learnjava/util/LocalDateAdapter.java @@ -0,0 +1,18 @@ +package com.learnjava.util; + +import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.time.LocalDate; + +public class LocalDateAdapter extends XmlAdapter { + + @SuppressWarnings("RedundantThrows") + @Override + public LocalDate unmarshal(String str) throws Exception { + return LocalDate.parse(str); + } + @SuppressWarnings("RedundantThrows") + @Override + public String marshal(LocalDate ld) throws Exception { + return ld.toString(); + } +} \ No newline at end of file diff --git a/src/com/learnjava/util/LocalDateTypeAdapter.java b/src/com/learnjava/util/LocalDateTypeAdapter.java new file mode 100644 index 0000000..997b5f7 --- /dev/null +++ b/src/com/learnjava/util/LocalDateTypeAdapter.java @@ -0,0 +1,24 @@ +package com.learnjava.util; + +import com.google.gson.*; + +import java.lang.reflect.Type; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class LocalDateTypeAdapter implements JsonSerializer, JsonDeserializer { + + private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + @Override + public JsonElement serialize(final LocalDate date, final Type typeOfSrc, + final JsonSerializationContext context) { + return new JsonPrimitive(date.format(formatter)); + } + + @Override + public LocalDate deserialize(final JsonElement json, final Type typeOfT, + final JsonDeserializationContext context) throws JsonParseException { + return LocalDate.parse(json.getAsString(), formatter); + } +} diff --git a/src/com/learnjava/util/XmlParser.java b/src/com/learnjava/util/XmlParser.java new file mode 100644 index 0000000..870138f --- /dev/null +++ b/src/com/learnjava/util/XmlParser.java @@ -0,0 +1,43 @@ +package com.learnjava.util; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import java.io.Reader; +import java.io.Writer; + +public class XmlParser { + private final Marshaller marshaller; + private final Unmarshaller unmarshaller; + + public XmlParser(Class... classesToBeBound) { + try { + JAXBContext ctx = JAXBContext.newInstance(classesToBeBound); + + marshaller = ctx.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); + + unmarshaller = ctx.createUnmarshaller(); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + } + + public T unmarshall(Reader reader) { + try { + return (T) unmarshaller.unmarshal(reader); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + } + + public void marshall(Object instance, Writer writer) { + try { + marshaller.marshal(instance, writer); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 1594147..0a99b6e 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -15,7 +15,7 @@ public abstract class AbstractStorageTest { protected static final File STORAGE_DIR = new File("D:\\YandexDisk\\_java_learn\\storage_files\\full"); protected static final File STORAGE_DIR_EMPTY = new File("D:\\YandexDisk\\_java_learn\\storage_files\\empty"); - private static final String UUID_1 = "uuid1"; + private static final String UUID_1 = "uuid 1"; private static final Resume RESUME_1 = getFilledResume(UUID_1, "Ivanov"); private static final String UUID_2 = "uuid2"; private static final Resume RESUME_2 = getFilledResume(UUID_2, "Petrov"); diff --git a/test/com/learnjava/storage/FileStorageTest.java b/test/com/learnjava/storage/FileStorageTest.java index 978c660..ae62767 100644 --- a/test/com/learnjava/storage/FileStorageTest.java +++ b/test/com/learnjava/storage/FileStorageTest.java @@ -1,9 +1,6 @@ package com.learnjava.storage; - import com.learnjava.storage.serializer.ObjectStreamSerializer; - public class FileStorageTest extends AbstractStorageTest { - public FileStorageTest() { super(new FileStorage(STORAGE_DIR, new ObjectStreamSerializer()), (new FileStorage(STORAGE_DIR_EMPTY, new ObjectStreamSerializer()))); } diff --git a/test/com/learnjava/storage/JsonPathStorageTest.java b/test/com/learnjava/storage/JsonPathStorageTest.java new file mode 100644 index 0000000..47f77c6 --- /dev/null +++ b/test/com/learnjava/storage/JsonPathStorageTest.java @@ -0,0 +1,8 @@ +package com.learnjava.storage; +import com.learnjava.storage.serializer.JsonStreamSerializer; +public class JsonPathStorageTest extends AbstractStorageTest { + + public JsonPathStorageTest() { + super(new PathStorage(STORAGE_DIR.getAbsolutePath(), new JsonStreamSerializer()),new PathStorage(STORAGE_DIR_EMPTY.getAbsolutePath(), new JsonStreamSerializer())); + } +} \ No newline at end of file diff --git a/test/com/learnjava/storage/PathStorageTest.java b/test/com/learnjava/storage/PathStorageTest.java index 8b6a765..c324a7f 100644 --- a/test/com/learnjava/storage/PathStorageTest.java +++ b/test/com/learnjava/storage/PathStorageTest.java @@ -1,9 +1,9 @@ package com.learnjava.storage; -import com.learnjava.storage.serializer.ObjectStreamSerializer; +import com.learnjava.storage.serializer.DataStreamSerializer; public class PathStorageTest extends AbstractStorageTest { public PathStorageTest() { - super(new PathStorage(STORAGE_DIR.getAbsolutePath(), new ObjectStreamSerializer()), (new PathStorage(STORAGE_DIR_EMPTY.getAbsolutePath(), new ObjectStreamSerializer()))); + super(new PathStorage(STORAGE_DIR.getAbsolutePath(), new DataStreamSerializer()), (new PathStorage(STORAGE_DIR_EMPTY.getAbsolutePath(), new DataStreamSerializer()))); } } diff --git a/test/com/learnjava/storage/XmlPathStorageTest.java b/test/com/learnjava/storage/XmlPathStorageTest.java new file mode 100644 index 0000000..f80d849 --- /dev/null +++ b/test/com/learnjava/storage/XmlPathStorageTest.java @@ -0,0 +1,9 @@ +package com.learnjava.storage; + +import com.learnjava.storage.serializer.XmlStreamSerializer; + +public class XmlPathStorageTest extends AbstractStorageTest { + public XmlPathStorageTest() { + super(new PathStorage(STORAGE_DIR.getAbsolutePath(), new XmlStreamSerializer()), new PathStorage(STORAGE_DIR_EMPTY.getAbsolutePath(), new XmlStreamSerializer())); + } +} diff --git a/test/com/learnjava/storage/everyStorageTest.java b/test/com/learnjava/storage/everyStorageTest.java index 3bddaf9..f416013 100644 --- a/test/com/learnjava/storage/everyStorageTest.java +++ b/test/com/learnjava/storage/everyStorageTest.java @@ -11,7 +11,9 @@ MapStorageTest.class, MapUUIDStorageTest.class, FileStorageTest.class, - PathStorageTest.class + PathStorageTest.class, + JsonPathStorageTest.class, + XmlPathStorageTest.class }) public class everyStorageTest { From 54b711116a8a1797a5c8d224901fe57e9bdd6bab Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:56:03 +0300 Subject: [PATCH 61/71] =?UTF-8?q?Revert=20"HW09=20=D0=B4=D1=80=D1=83=D0=B3?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=20=D0=B4?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B2=D0=B0=20=D0=BA=D0=B0=D1=82=D0=B0=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=D0=B2=20=D0=B8=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit b79781964ddf81a727b634bdf24493b366365239. --- src/com/learnjava/MainFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/learnjava/MainFile.java b/src/com/learnjava/MainFile.java index 6869565..38aa0ad 100644 --- a/src/com/learnjava/MainFile.java +++ b/src/com/learnjava/MainFile.java @@ -42,7 +42,7 @@ public static void printDirectoryDeeply(File dir, int deep) { if (files != null) { for (File file : files) { if (file.isFile()) { - System.out.println("File: " + new String(spaces) + file.getName()); + System.out.println("File: " + new String(spaces) + file.getName()); } } for (File file : files) { From 07de1dac87879d6c03e5daca5039e0804a13a5e8 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Tue, 8 Aug 2023 21:18:43 +0300 Subject: [PATCH 62/71] =?UTF-8?q?HW11=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20deadlock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/DeadLock.java | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/com/learnjava/DeadLock.java diff --git a/src/com/learnjava/DeadLock.java b/src/com/learnjava/DeadLock.java new file mode 100644 index 0000000..37f7937 --- /dev/null +++ b/src/com/learnjava/DeadLock.java @@ -0,0 +1,35 @@ +package com.learnjava; + +public class DeadLock { + public static void main(String[] args) { + + final String resource1 = "Chicken"; + final String resource2 = "Egg"; + + Thread t1 = new Thread(() -> { + synchronized (resource1) { + System.out.println("Thread 1: locked " + resource1 ); + + try { Thread.sleep(100);} catch (Exception ignored) {} + + synchronized (resource2) { + System.out.println("Thread 1: locked" + resource1); + } + } + }); + + Thread t2 = new Thread(() -> { + synchronized (resource2) { + System.out.println("Thread 2: locked " + resource2); + + try { Thread.sleep(100);} catch (Exception ignored) {} + + synchronized (resource1) { + System.out.println("Thread 2: locked " + resource2); + } + } + }); + t1.start(); + t2.start(); + } +} From 3cfc529d5455d940d942fbc8c3d2cfe0bfa50861 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Wed, 9 Aug 2023 16:46:02 +0300 Subject: [PATCH 63/71] =?UTF-8?q?HW12=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B=202=20=D1=83=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/HomeWork12Exercise.java | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/com/learnjava/HomeWork12Exercise.java diff --git a/src/com/learnjava/HomeWork12Exercise.java b/src/com/learnjava/HomeWork12Exercise.java new file mode 100644 index 0000000..75fcbd2 --- /dev/null +++ b/src/com/learnjava/HomeWork12Exercise.java @@ -0,0 +1,45 @@ +package com.learnjava; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; + +public class HomeWork12Exercise { + public static int minValue(int[] values) { + int answer = 0; + int[] uniqueFigure = new int[10]; + IntStream inputStream = Arrays.stream(values); + inputStream.forEach(num -> uniqueFigure[num] = 1); + for (int i = 1; i < 10; i++) { + if (uniqueFigure[i] == 1) { + answer = answer * 10 + i; + } + } + return answer; + } + + public static List oddOrEven(List integers) { + List even = new ArrayList<>(); + List odd = new ArrayList<>(); + integers.forEach(integer -> { + if (integer % 2 == 0) { + even.add(integer); + } else { + odd.add(integer); + } + }); + if (odd.size() % 2 == 0) { + return odd; + } else { + return even; + } + } + + public static void main(String[] args) { + int[] arr = {1, 1, 2, 1, 4, 5, 5, 9, 8}; + System.out.println("Минимальное значение по условиям задачи: " + minValue(arr)); + List intList = Arrays.asList(1, 2, 3, 4, 5, 6); + System.out.println("четные или не четные числа: " + oddOrEven(intList)); + } +} From f7a533e3f9582343768434b86b04f640ab741bd3 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Thu, 10 Aug 2023 16:27:49 +0300 Subject: [PATCH 64/71] =?UTF-8?q?HW12=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=B5=20=D1=81=D1=82=D1=80=D0=B8=D0=BC=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/HomeWork12Exercise.java | 34 ++++++----------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/com/learnjava/HomeWork12Exercise.java b/src/com/learnjava/HomeWork12Exercise.java index 75fcbd2..f461c5f 100644 --- a/src/com/learnjava/HomeWork12Exercise.java +++ b/src/com/learnjava/HomeWork12Exercise.java @@ -1,45 +1,29 @@ package com.learnjava; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.stream.IntStream; +import java.util.stream.Collectors; public class HomeWork12Exercise { public static int minValue(int[] values) { - int answer = 0; - int[] uniqueFigure = new int[10]; - IntStream inputStream = Arrays.stream(values); - inputStream.forEach(num -> uniqueFigure[num] = 1); - for (int i = 1; i < 10; i++) { - if (uniqueFigure[i] == 1) { - answer = answer * 10 + i; - } - } - return answer; + return Arrays.stream(values).sorted().distinct().reduce(0, (subResult, currentNum) -> subResult * 10 + currentNum); } public static List oddOrEven(List integers) { - List even = new ArrayList<>(); - List odd = new ArrayList<>(); - integers.forEach(integer -> { - if (integer % 2 == 0) { - even.add(integer); - } else { - odd.add(integer); - } - }); - if (odd.size() % 2 == 0) { - return odd; + List> oddEven = integers.stream().collect(Collectors.teeing( + Collectors.filtering(num -> num % 2 == 0, Collectors.toList()), + Collectors.filtering(num -> num % 2 != 0, Collectors.toList()), List::of)); + if (oddEven.get(0).size() % 2 == 0) { + return oddEven.get(1); } else { - return even; + return oddEven.get(0); } } public static void main(String[] args) { int[] arr = {1, 1, 2, 1, 4, 5, 5, 9, 8}; System.out.println("Минимальное значение по условиям задачи: " + minValue(arr)); - List intList = Arrays.asList(1, 2, 3, 4, 5, 6); + List intList = Arrays.asList(1, 2, 3, 7, 8); System.out.println("четные или не четные числа: " + oddOrEven(intList)); } } From 78849472e8b2520eaed8e6d602db6d5247123ad9 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Sat, 12 Aug 2023 20:03:27 +0300 Subject: [PATCH 65/71] =?UTF-8?q?HW12=20=D0=B2=20=D0=BF=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=83=D0=BF=D1=80=D0=B0=D0=B6=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B1=D0=B8=D1=82=D0=BE=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=B5=D1=81=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA?= =?UTF-8?q?=D0=BE=20=D1=81=D1=82=D1=80=D0=BE=D0=BA.=20=D0=92=D0=BE=20?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=BE=D0=BC=20=D0=B8=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20Collectors.partiti?= =?UTF-8?q?oningBy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/HomeWork12Exercise.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/com/learnjava/HomeWork12Exercise.java b/src/com/learnjava/HomeWork12Exercise.java index f461c5f..258d845 100644 --- a/src/com/learnjava/HomeWork12Exercise.java +++ b/src/com/learnjava/HomeWork12Exercise.java @@ -1,18 +1,24 @@ package com.learnjava; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class HomeWork12Exercise { public static int minValue(int[] values) { - return Arrays.stream(values).sorted().distinct().reduce(0, (subResult, currentNum) -> subResult * 10 + currentNum); + return Arrays.stream(values) + .sorted() + .distinct() + .reduce(0, (subResult, currentNum) -> subResult * 10 + currentNum); } public static List oddOrEven(List integers) { - List> oddEven = integers.stream().collect(Collectors.teeing( - Collectors.filtering(num -> num % 2 == 0, Collectors.toList()), - Collectors.filtering(num -> num % 2 != 0, Collectors.toList()), List::of)); + + Map> map = integers.stream() + .collect(Collectors.partitioningBy(num -> num % 2 == 0)); + List> oddEven = new ArrayList<>(map.values()); if (oddEven.get(0).size() % 2 == 0) { return oddEven.get(1); } else { @@ -23,7 +29,7 @@ public static List oddOrEven(List integers) { public static void main(String[] args) { int[] arr = {1, 1, 2, 1, 4, 5, 5, 9, 8}; System.out.println("Минимальное значение по условиям задачи: " + minValue(arr)); - List intList = Arrays.asList(1, 2, 3, 7, 8); + List intList = Arrays.asList(1, 2, 3, 7, 8, 3); System.out.println("четные или не четные числа: " + oddOrEven(intList)); } } From f40f62662ccc54361e21d7056a4f7c142d0ada91 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Sun, 13 Aug 2023 10:57:03 +0300 Subject: [PATCH 66/71] =?UTF-8?q?HW12=20=D0=B2=20=D0=BF=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=83=D0=BF=D1=80=D0=B0=D0=B6=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B1=D0=B8=D1=82=D0=BE=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=B5=D1=81=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA?= =?UTF-8?q?=D0=BE=20=D1=81=D1=82=D1=80=D0=BE=D0=BA.=20=D0=92=D0=BE=20?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=BE=D0=BC=20=D0=B8=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20Collectors.partiti?= =?UTF-8?q?oningBy,=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D1=87=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=20=D1=82=D0=B5=D1=80=D0=BD=D0=B0=D1=80=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/HomeWork12Exercise.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/com/learnjava/HomeWork12Exercise.java b/src/com/learnjava/HomeWork12Exercise.java index 258d845..b244171 100644 --- a/src/com/learnjava/HomeWork12Exercise.java +++ b/src/com/learnjava/HomeWork12Exercise.java @@ -19,11 +19,7 @@ public static List oddOrEven(List integers) { Map> map = integers.stream() .collect(Collectors.partitioningBy(num -> num % 2 == 0)); List> oddEven = new ArrayList<>(map.values()); - if (oddEven.get(0).size() % 2 == 0) { - return oddEven.get(1); - } else { - return oddEven.get(0); - } + return (oddEven.get(0).size() % 2 == 0) ? oddEven.get(1): oddEven.get(0) ; } public static void main(String[] args) { From 6c9d24c0d7aab1abac948271d44c57501a0e61d3 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Mon, 14 Aug 2023 08:54:00 +0300 Subject: [PATCH 67/71] HW12 fix + merge --- src/com/learnjava/HomeWork12Exercise.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/com/learnjava/HomeWork12Exercise.java b/src/com/learnjava/HomeWork12Exercise.java index b244171..e16f961 100644 --- a/src/com/learnjava/HomeWork12Exercise.java +++ b/src/com/learnjava/HomeWork12Exercise.java @@ -1,6 +1,5 @@ package com.learnjava; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -18,8 +17,7 @@ public static List oddOrEven(List integers) { Map> map = integers.stream() .collect(Collectors.partitioningBy(num -> num % 2 == 0)); - List> oddEven = new ArrayList<>(map.values()); - return (oddEven.get(0).size() % 2 == 0) ? oddEven.get(1): oddEven.get(0) ; + return map.get(false).size() % 2 == 0 ? map.get(true) : map.get(false); } public static void main(String[] args) { From 4848c6a6b5012883311d3a5722271335b3c9dc4f Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Mon, 14 Aug 2023 15:00:32 +0300 Subject: [PATCH 68/71] =?UTF-8?q?HW13=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20SqlStorage,=20SqlStorageTest,?= =?UTF-8?q?=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=89=D0=B8=D0=B9=20=D0=BA=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/init_db.sql | 13 +++ config/resumes.properties | 5 ++ src/com/learnjava/Config.java | 49 +++++++++++ src/com/learnjava/ResumeTestData.java | 12 ++- .../learnjava/exception/StorageException.java | 7 ++ src/com/learnjava/sql/ConnectionFactory.java | 8 ++ src/com/learnjava/sql/ExceptionUtil.java | 22 +++++ src/com/learnjava/sql/SqlExecutor.java | 9 ++ src/com/learnjava/sql/SqlHelper.java | 26 ++++++ src/com/learnjava/storage/SqlStorage.java | 87 +++++++++++++++++++ .../storage/AbstractStorageTest.java | 10 ++- .../com/learnjava/storage/SqlStorageTest.java | 10 +++ .../learnjava/storage/everyStorageTest.java | 3 +- 13 files changed, 250 insertions(+), 11 deletions(-) create mode 100644 config/init_db.sql create mode 100644 config/resumes.properties create mode 100644 src/com/learnjava/Config.java create mode 100644 src/com/learnjava/sql/ConnectionFactory.java create mode 100644 src/com/learnjava/sql/ExceptionUtil.java create mode 100644 src/com/learnjava/sql/SqlExecutor.java create mode 100644 src/com/learnjava/sql/SqlHelper.java create mode 100644 src/com/learnjava/storage/SqlStorage.java create mode 100644 test/com/learnjava/storage/SqlStorageTest.java diff --git a/config/init_db.sql b/config/init_db.sql new file mode 100644 index 0000000..88bad82 --- /dev/null +++ b/config/init_db.sql @@ -0,0 +1,13 @@ +CREATE TABLE resume ( + uuid CHAR(36) PRIMARY KEY NOT NULL, + full_name TEXT NOT NULL +); + +CREATE TABLE contact ( + id SERIAL, + resume_uuid CHAR(36) NOT NULL REFERENCES resume (uuid) ON DELETE CASCADE, + type TEXT NOT NULL, + value TEXT NOT NULL +); +CREATE UNIQUE INDEX contact_uuid_type_index + ON contact (resume_uuid, type); \ No newline at end of file diff --git a/config/resumes.properties b/config/resumes.properties new file mode 100644 index 0000000..f1468cf --- /dev/null +++ b/config/resumes.properties @@ -0,0 +1,5 @@ +storage.dir=D:/YandexDisk/_java_learn/storage_files/full +storage.emptyDir=D:/YandexDisk/_java_learn/storage_files/empty +db.url=jdbc:postgresql://localhost:5432/resumes +db.user=postgres +db.password=postgres \ No newline at end of file diff --git a/src/com/learnjava/Config.java b/src/com/learnjava/Config.java new file mode 100644 index 0000000..74fda2e --- /dev/null +++ b/src/com/learnjava/Config.java @@ -0,0 +1,49 @@ +package com.learnjava; + +import com.learnjava.storage.SqlStorage; +import com.learnjava.storage.Storage; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class Config { + private static final File PROPS = new File("config\\resumes.properties"); + private static final Config INSTANCE = new Config(); + + private final File storageDir; + private final File storageDirEmpty; + private final Storage storage; + + + public static Config get() { + return INSTANCE; + } + + private Config() { + try (InputStream is = new FileInputStream(PROPS)) { + Properties props = new Properties(); + props.load(is); + storageDir = new File(props.getProperty("storage.dir")); + storageDirEmpty = new File(props.getProperty("storage.emptyDir")); + storage = new SqlStorage(props.getProperty("db.url"), props.getProperty("db.user"), props.getProperty("db.password")); + } catch (IOException e) { + throw new IllegalStateException("Invalid config file " + PROPS.getAbsolutePath()); + } + } + + public File getStorageDir() { + return storageDir; + } + + public File getStorageDirEmpty() { + return storageDirEmpty; + } + + public Storage getStorage() { + return storage; + } + +} diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index 41dbf02..c600a1a 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -1,9 +1,7 @@ package com.learnjava; -import com.learnjava.model.*; +import com.learnjava.model.Resume; -import java.time.LocalDate; -import java.util.Arrays; import java.util.UUID; import static com.learnjava.model.ContactType.*; @@ -35,10 +33,10 @@ public static Resume getFilledResume(String uuid, String fullName) { resumeWData.addContact(GITHUB, "github.com/gkislin"); resumeWData.addContact(STATCKOVERFLOW, "stackoverflow.com/users/548473"); resumeWData.addContact(HOME_PAGE, "gkislin.ru/"); - resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); - resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); - resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( - new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); +// resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); +// resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); +// resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( +// new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); return resumeWData; } diff --git a/src/com/learnjava/exception/StorageException.java b/src/com/learnjava/exception/StorageException.java index 61f5040..850858f 100644 --- a/src/com/learnjava/exception/StorageException.java +++ b/src/com/learnjava/exception/StorageException.java @@ -1,5 +1,6 @@ package com.learnjava.exception; + public class StorageException extends RuntimeException { private final String uuid; @@ -11,9 +12,15 @@ public StorageException(String message, String uuid) { super(message); this.uuid = uuid; } + + public StorageException(Exception e) { + this(e.getMessage(), e); + } + public StorageException(String message, Exception e) { this(message, null, e); } + public StorageException(String message, String uuid, Exception e) { super(message, e); this.uuid = uuid; diff --git a/src/com/learnjava/sql/ConnectionFactory.java b/src/com/learnjava/sql/ConnectionFactory.java new file mode 100644 index 0000000..9afd543 --- /dev/null +++ b/src/com/learnjava/sql/ConnectionFactory.java @@ -0,0 +1,8 @@ +package com.learnjava.sql; + +import java.sql.Connection; +import java.sql.SQLException; + +public interface ConnectionFactory { + Connection getConnection() throws SQLException; +} \ No newline at end of file diff --git a/src/com/learnjava/sql/ExceptionUtil.java b/src/com/learnjava/sql/ExceptionUtil.java new file mode 100644 index 0000000..b433826 --- /dev/null +++ b/src/com/learnjava/sql/ExceptionUtil.java @@ -0,0 +1,22 @@ +package com.learnjava.sql; + +import org.postgresql.util.PSQLException; +import com.learnjava.exception.ExistStorageException; +import com.learnjava.exception.StorageException; + +import java.sql.SQLException; + +public class ExceptionUtil { + private ExceptionUtil() { + } + + public static StorageException convertException(SQLException e) { + if (e instanceof PSQLException) { + + if (e.getSQLState().equals("23505")) { + return new ExistStorageException(null); + } + } + return new StorageException(e); + } +} \ No newline at end of file diff --git a/src/com/learnjava/sql/SqlExecutor.java b/src/com/learnjava/sql/SqlExecutor.java new file mode 100644 index 0000000..c1c56a8 --- /dev/null +++ b/src/com/learnjava/sql/SqlExecutor.java @@ -0,0 +1,9 @@ +package com.learnjava.sql; + + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public interface SqlExecutor { + T execute(PreparedStatement st) throws SQLException; +} \ No newline at end of file diff --git a/src/com/learnjava/sql/SqlHelper.java b/src/com/learnjava/sql/SqlHelper.java new file mode 100644 index 0000000..e8d5492 --- /dev/null +++ b/src/com/learnjava/sql/SqlHelper.java @@ -0,0 +1,26 @@ +package com.learnjava.sql; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class SqlHelper { + private final ConnectionFactory connectionFactory; + + public SqlHelper(ConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + public void execute(String sql) { + execute(sql, PreparedStatement::execute); + } + + public T execute(String sql, SqlExecutor executor) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + return executor.execute(ps); + } catch (SQLException e) { + throw ExceptionUtil.convertException(e); + } + } +} \ No newline at end of file diff --git a/src/com/learnjava/storage/SqlStorage.java b/src/com/learnjava/storage/SqlStorage.java new file mode 100644 index 0000000..8695f3c --- /dev/null +++ b/src/com/learnjava/storage/SqlStorage.java @@ -0,0 +1,87 @@ +package com.learnjava.storage; + +import com.learnjava.exception.NotExistStorageException; +import com.learnjava.model.Resume; +import com.learnjava.sql.SqlHelper; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; + +public class SqlStorage implements Storage { + public final SqlHelper sqlHelper; + + public SqlStorage(String dbUrl, String dbUser, String dbPassword) { + sqlHelper = new SqlHelper(() -> DriverManager.getConnection(dbUrl, dbUser, dbPassword)); + } + + @Override + public void clear() { + sqlHelper.execute("DELETE FROM resume"); + } + + @Override + public Resume get(String uuid) { + return sqlHelper.execute("SELECT * FROM resume r WHERE r.uuid =?", ps -> { + ps.setString(1, uuid); + ResultSet rs = ps.executeQuery(); + if (!rs.next()) { + throw new NotExistStorageException(uuid); + } + return new Resume(uuid, rs.getString("full_name")); + }); + } + + @Override + public void update(Resume r) { + sqlHelper.execute("UPDATE resume SET full_name = ? WHERE uuid = ?", ps -> { + ps.setString(1, r.getFullName()); + ps.setString(2, r.getUuid()); + if (ps.executeUpdate() == 0) { + throw new NotExistStorageException(r.getUuid()); + } + return null; + }); + } + + @Override + public void save(Resume r) { + sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", ps -> { + ps.setString(1, r.getUuid()); + ps.setString(2, r.getFullName()); + ps.execute(); + return null; + }); + } + + @Override + public void delete(String uuid) { + sqlHelper.execute("DELETE FROM resume WHERE uuid=?", ps -> { + ps.setString(1, uuid); + if (ps.executeUpdate() == 0) { + throw new NotExistStorageException(uuid); + } + return null; + }); + } + + @Override + public List getAllSorted() { + return sqlHelper.execute("SELECT * FROM resume r ORDER BY full_name,uuid", ps -> { + ResultSet rs = ps.executeQuery(); + List resumes = new ArrayList<>(); + while (rs.next()) { + resumes.add(new Resume(rs.getString("uuid").trim(), rs.getString("full_name").trim())); + } + return resumes; + }); + } + + @Override + public int size() { + return sqlHelper.execute("SELECT count(*) FROM resume", st -> { + ResultSet rs = st.executeQuery(); + return rs.next() ? rs.getInt(1) : 0; + }); + } +} \ No newline at end of file diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 0a99b6e..4abad22 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -1,5 +1,6 @@ package com.learnjava.storage; +import com.learnjava.Config; import com.learnjava.exception.NotExistStorageException; import com.learnjava.model.Resume; import org.junit.jupiter.api.Assertions; @@ -13,8 +14,8 @@ import static com.learnjava.ResumeTestData.getFilledResume; public abstract class AbstractStorageTest { - protected static final File STORAGE_DIR = new File("D:\\YandexDisk\\_java_learn\\storage_files\\full"); - protected static final File STORAGE_DIR_EMPTY = new File("D:\\YandexDisk\\_java_learn\\storage_files\\empty"); + protected static final File STORAGE_DIR = Config.get().getStorageDir(); + protected static final File STORAGE_DIR_EMPTY = Config.get().getStorageDirEmpty(); private static final String UUID_1 = "uuid 1"; private static final Resume RESUME_1 = getFilledResume(UUID_1, "Ivanov"); private static final String UUID_2 = "uuid2"; @@ -33,6 +34,10 @@ protected AbstractStorageTest(Storage storage, Storage emptyStorage) { this.emptyStorage = emptyStorage; } + protected AbstractStorageTest(Storage storage) { + this.storage = storage; + } + @BeforeEach public void beforeEach() { if (storage != null) { @@ -60,7 +65,6 @@ void size() { void clear() { storage.clear(); assertSize(0); - Assertions.assertArrayEquals(storage.getAllSorted().toArray(), emptyStorage.getAllSorted().toArray()); } @Test diff --git a/test/com/learnjava/storage/SqlStorageTest.java b/test/com/learnjava/storage/SqlStorageTest.java new file mode 100644 index 0000000..8b1a2b5 --- /dev/null +++ b/test/com/learnjava/storage/SqlStorageTest.java @@ -0,0 +1,10 @@ +package com.learnjava.storage; + +import com.learnjava.Config; + +public class SqlStorageTest extends AbstractStorageTest { + + public SqlStorageTest() { + super(Config.get().getStorage()); + } +} \ No newline at end of file diff --git a/test/com/learnjava/storage/everyStorageTest.java b/test/com/learnjava/storage/everyStorageTest.java index f416013..8652256 100644 --- a/test/com/learnjava/storage/everyStorageTest.java +++ b/test/com/learnjava/storage/everyStorageTest.java @@ -13,7 +13,8 @@ FileStorageTest.class, PathStorageTest.class, JsonPathStorageTest.class, - XmlPathStorageTest.class + XmlPathStorageTest.class, + SqlStorageTest.class }) public class everyStorageTest { From 47f8ca9afcc1d0bde7a017a744a0b774990352ec Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Tue, 15 Aug 2023 17:04:28 +0300 Subject: [PATCH 69/71] =?UTF-8?q?HW13=20=D1=83=D0=B1=D1=80=D0=B0=D0=BD=20t?= =?UTF-8?q?rim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/storage/SqlStorage.java | 2 +- .../storage/AbstractStorageTest.java | 29 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/com/learnjava/storage/SqlStorage.java b/src/com/learnjava/storage/SqlStorage.java index 8695f3c..9037e50 100644 --- a/src/com/learnjava/storage/SqlStorage.java +++ b/src/com/learnjava/storage/SqlStorage.java @@ -71,7 +71,7 @@ public List getAllSorted() { ResultSet rs = ps.executeQuery(); List resumes = new ArrayList<>(); while (rs.next()) { - resumes.add(new Resume(rs.getString("uuid").trim(), rs.getString("full_name").trim())); + resumes.add(new Resume(rs.getString("uuid"), rs.getString("full_name"))); } return resumes; }); diff --git a/test/com/learnjava/storage/AbstractStorageTest.java b/test/com/learnjava/storage/AbstractStorageTest.java index 4abad22..2f6028c 100644 --- a/test/com/learnjava/storage/AbstractStorageTest.java +++ b/test/com/learnjava/storage/AbstractStorageTest.java @@ -8,24 +8,25 @@ import org.junit.jupiter.api.Test; import java.io.File; -import java.util.Arrays; -import java.util.List; +import java.util.*; import static com.learnjava.ResumeTestData.getFilledResume; public abstract class AbstractStorageTest { protected static final File STORAGE_DIR = Config.get().getStorageDir(); protected static final File STORAGE_DIR_EMPTY = Config.get().getStorageDirEmpty(); - private static final String UUID_1 = "uuid 1"; + private static final List sortedUuidList = generateSortedUuid(5); + private static final String UUID_1 = readSortedUuidList(0); private static final Resume RESUME_1 = getFilledResume(UUID_1, "Ivanov"); - private static final String UUID_2 = "uuid2"; + private static final String UUID_2 = readSortedUuidList(1); private static final Resume RESUME_2 = getFilledResume(UUID_2, "Petrov"); - private static final String UUID_3 = "uuid3"; + private static final String UUID_3 = readSortedUuidList(2); private static final Resume RESUME_3 = getFilledResume(UUID_3, "Sidorov"); - private static final String UUID_4 = "extra_uuid"; + private static final String UUID_4 = readSortedUuidList(3); private static final Resume RESUME_4 = getFilledResume(UUID_4, "Kuznetcov"); - private static final String UUID_NOT_EXIST = "NON_EXISTENT_UUID"; + private static final String UUID_NOT_EXIST = readSortedUuidList(4); private static final Resume RESUME_5 = getFilledResume(UUID_NOT_EXIST, "Gzhegosh"); + protected Storage storage; protected Storage emptyStorage; @@ -38,6 +39,19 @@ protected AbstractStorageTest(Storage storage) { this.storage = storage; } + private static List generateSortedUuid(int quan) { + List sortedList = new ArrayList<>(); + for (int i = 0; i < quan; i++) { + sortedList.add(UUID.randomUUID().toString()); + } + Collections.sort(sortedList); + return sortedList; + } + + private static String readSortedUuidList(int index) { + return sortedUuidList.get(index); + } + @BeforeEach public void beforeEach() { if (storage != null) { @@ -116,4 +130,5 @@ void deleteNotExist() { public void updateNotExist() { Assertions.assertThrows(NotExistStorageException.class, () -> storage.update(RESUME_5)); } + } From 52699f8f228f5faaa413b03acd7c62b35d0660d3 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Tue, 15 Aug 2023 18:40:40 +0300 Subject: [PATCH 70/71] =?UTF-8?q?HW14=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=81=D0=B5=D0=BA=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/ResumeTestData.java | 12 +- src/com/learnjava/model/Resume.java | 13 ++ src/com/learnjava/sql/SqlHelper.java | 18 ++ src/com/learnjava/sql/SqlTransaction.java | 9 + src/com/learnjava/storage/SqlStorage.java | 169 +++++++++++++++--- .../serializer/JsonStreamSerializer.java | 1 + src/com/learnjava/util/JsonParser.java | 14 +- 7 files changed, 204 insertions(+), 32 deletions(-) create mode 100644 src/com/learnjava/sql/SqlTransaction.java diff --git a/src/com/learnjava/ResumeTestData.java b/src/com/learnjava/ResumeTestData.java index c600a1a..41dbf02 100644 --- a/src/com/learnjava/ResumeTestData.java +++ b/src/com/learnjava/ResumeTestData.java @@ -1,7 +1,9 @@ package com.learnjava; -import com.learnjava.model.Resume; +import com.learnjava.model.*; +import java.time.LocalDate; +import java.util.Arrays; import java.util.UUID; import static com.learnjava.model.ContactType.*; @@ -33,10 +35,10 @@ public static Resume getFilledResume(String uuid, String fullName) { resumeWData.addContact(GITHUB, "github.com/gkislin"); resumeWData.addContact(STATCKOVERFLOW, "stackoverflow.com/users/548473"); resumeWData.addContact(HOME_PAGE, "gkislin.ru/"); -// resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); -// resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); -// resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( -// new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); + resumeWData.addSection(OBJECTIVE, new TextSection("Ведущий стажировок и корпоративного обучения по Java Web и Enterprise технологиям ")); + resumeWData.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("Достижение1", "Достижение2", "Достижение3"))); + resumeWData.addSection(SectionType.EXPERIENCE, new OrganizationSection(Arrays.asList( + new Organization("Java Online Projects", "https://javaops.ru/", Arrays.asList(new Period(LocalDate.of(2013, 10, 1), LocalDate.now(), "Автор проекта.", "Создание, организация и проведение Java онлайн проектов и стажировок."))), new Organization("Wrike", "https://www.wrike.com/aa/", Arrays.asList(new Period(LocalDate.of(2014, 10, 1), LocalDate.of(2016, 1, 1), "Старший разработчик (backend)", "Проектирование и разработка онлайн платформы управления проектами Wrike (Java 8 API, Maven, Spring, MyBatis, Guava, Vaadin, PostgreSQL, Redis). Двухфакторная аутентификация, авторизация по OAuth1, OAuth2, JWT SSO.")))))); return resumeWData; } diff --git a/src/com/learnjava/model/Resume.java b/src/com/learnjava/model/Resume.java index 50949be..168976c 100644 --- a/src/com/learnjava/model/Resume.java +++ b/src/com/learnjava/model/Resume.java @@ -99,4 +99,17 @@ public int compareTo(Resume o) { int compareFullName = fullName.compareTo(o.fullName); return compareFullName == 0 ? uuid.compareTo(o.uuid) : compareFullName; } + + + + + + + public void setContact(ContactType type, String value) { + contacts.put(type, value); + } + + public void setSection(SectionType type, Section section) { + sections.put(type, section); + } } \ No newline at end of file diff --git a/src/com/learnjava/sql/SqlHelper.java b/src/com/learnjava/sql/SqlHelper.java index e8d5492..b4858cb 100644 --- a/src/com/learnjava/sql/SqlHelper.java +++ b/src/com/learnjava/sql/SqlHelper.java @@ -1,5 +1,7 @@ package com.learnjava.sql; +import com.learnjava.exception.StorageException; + import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -23,4 +25,20 @@ public T execute(String sql, SqlExecutor executor) { throw ExceptionUtil.convertException(e); } } + + public T transactionalExecute(SqlTransaction executor) { + try (Connection conn = connectionFactory.getConnection()) { + try { + conn.setAutoCommit(false); + T res = executor.execute(conn); + conn.commit(); + return res; + } catch (SQLException e) { + conn.rollback(); + throw ExceptionUtil.convertException(e); + } + } catch (SQLException e) { + throw new StorageException(e); + } + } } \ No newline at end of file diff --git a/src/com/learnjava/sql/SqlTransaction.java b/src/com/learnjava/sql/SqlTransaction.java new file mode 100644 index 0000000..a237f4f --- /dev/null +++ b/src/com/learnjava/sql/SqlTransaction.java @@ -0,0 +1,9 @@ +package com.learnjava.sql; + + +import java.sql.Connection; +import java.sql.SQLException; + +public interface SqlTransaction { + T execute(Connection conn) throws SQLException; +} \ No newline at end of file diff --git a/src/com/learnjava/storage/SqlStorage.java b/src/com/learnjava/storage/SqlStorage.java index 9037e50..4e1ec9c 100644 --- a/src/com/learnjava/storage/SqlStorage.java +++ b/src/com/learnjava/storage/SqlStorage.java @@ -1,17 +1,28 @@ package com.learnjava.storage; import com.learnjava.exception.NotExistStorageException; +import com.learnjava.model.ContactType; import com.learnjava.model.Resume; +import com.learnjava.model.Section; +import com.learnjava.model.SectionType; import com.learnjava.sql.SqlHelper; -import java.sql.DriverManager; -import java.sql.ResultSet; +import com.learnjava.util.JsonParser; + +import java.sql.*; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; public class SqlStorage implements Storage { public final SqlHelper sqlHelper; public SqlStorage(String dbUrl, String dbUser, String dbPassword) { + try { + Class.forName("org.postgresql.Driver"); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } sqlHelper = new SqlHelper(() -> DriverManager.getConnection(dbUrl, dbUser, dbPassword)); } @@ -22,36 +33,68 @@ public void clear() { @Override public Resume get(String uuid) { - return sqlHelper.execute("SELECT * FROM resume r WHERE r.uuid =?", ps -> { - ps.setString(1, uuid); - ResultSet rs = ps.executeQuery(); - if (!rs.next()) { - throw new NotExistStorageException(uuid); + return sqlHelper.transactionalExecute(conn -> { + Resume r; + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume WHERE uuid =?")) { + ps.setString(1, uuid); + ResultSet rs = ps.executeQuery(); + if (!rs.next()) { + throw new NotExistStorageException(uuid); + } + r = new Resume(uuid, rs.getString("full_name")); + } + + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM contact WHERE resume_uuid =?")) { + ps.setString(1, uuid); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + addContact(rs, r); + } } - return new Resume(uuid, rs.getString("full_name")); + + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM section WHERE resume_uuid =?")) { + ps.setString(1, uuid); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + addSection(rs, r); + } + } + + return r; }); } @Override public void update(Resume r) { - sqlHelper.execute("UPDATE resume SET full_name = ? WHERE uuid = ?", ps -> { - ps.setString(1, r.getFullName()); - ps.setString(2, r.getUuid()); - if (ps.executeUpdate() == 0) { - throw new NotExistStorageException(r.getUuid()); + sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { + ps.setString(1, r.getFullName()); + ps.setString(2, r.getUuid()); + if (ps.executeUpdate() != 1) { + throw new NotExistStorageException(r.getUuid()); + } } + deleteContacts(conn, r); + deleteSections(conn, r); + insertContacts(conn, r); + insertSections(conn, r); return null; }); } @Override public void save(Resume r) { - sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", ps -> { - ps.setString(1, r.getUuid()); - ps.setString(2, r.getFullName()); - ps.execute(); - return null; - }); + sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("INSERT INTO resume (uuid, full_name) VALUES (?,?)")) { + ps.setString(1, r.getUuid()); + ps.setString(2, r.getFullName()); + ps.execute(); + } + insertContacts(conn, r); + insertSections(conn, r); + return null; + } + ); } @Override @@ -67,13 +110,34 @@ public void delete(String uuid) { @Override public List getAllSorted() { - return sqlHelper.execute("SELECT * FROM resume r ORDER BY full_name,uuid", ps -> { - ResultSet rs = ps.executeQuery(); - List resumes = new ArrayList<>(); - while (rs.next()) { - resumes.add(new Resume(rs.getString("uuid"), rs.getString("full_name"))); + return sqlHelper.transactionalExecute(conn -> { + Map resumes = new LinkedHashMap<>(); + + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume ORDER BY full_name, uuid")) { + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + String uuid = rs.getString("uuid"); + resumes.put(uuid, new Resume(uuid, rs.getString("full_name"))); + } } - return resumes; + + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM contact")) { + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + Resume r = resumes.get(rs.getString("resume_uuid")); + addContact(rs, r); + } + } + + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM section")) { + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + Resume r = resumes.get(rs.getString("resume_uuid")); + addSection(rs, r); + } + } + + return new ArrayList<>(resumes.values()); }); } @@ -84,4 +148,59 @@ public int size() { return rs.next() ? rs.getInt(1) : 0; }); } + + private void insertContacts(Connection conn, Resume r) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement("INSERT INTO contact (resume_uuid, type, value) VALUES (?,?,?)")) { + for (Map.Entry e : r.getContacts().entrySet()) { + ps.setString(1, r.getUuid()); + ps.setString(2, e.getKey().name()); + ps.setString(3, e.getValue()); + ps.addBatch(); + } + ps.executeBatch(); + } + } + + private void insertSections(Connection conn, Resume r) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement("INSERT INTO section (resume_uuid, type, content) VALUES (?,?,?)")) { + for (Map.Entry e : r.getSections().entrySet()) { + ps.setString(1, r.getUuid()); + ps.setString(2, e.getKey().name()); + Section section = e.getValue(); + ps.setString(3, JsonParser.write(section, Section.class)); + ps.addBatch(); + } + ps.executeBatch(); + } + } + + private void deleteContacts(Connection conn, Resume r) throws SQLException { + deleteAttributes(conn, r, "DELETE FROM contact WHERE resume_uuid=?"); + } + + private void deleteSections(Connection conn, Resume r) throws SQLException { + deleteAttributes(conn, r, "DELETE FROM section WHERE resume_uuid=?"); + } + + private void deleteAttributes(Connection conn, Resume r, String sql) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, r.getUuid()); + ps.execute(); + } + } + + private void addContact(ResultSet rs, Resume r) throws SQLException { + String value = rs.getString("value"); + if (value != null) { + r.setContact(ContactType.valueOf(rs.getString("type")), value); + } + } + + private void addSection(ResultSet rs, Resume r) throws SQLException { + String content = rs.getString("content"); + if (content != null) { + SectionType type = SectionType.valueOf(rs.getString("type")); + r.setSection(type, JsonParser.read(content, Section.class)); + } + } } \ No newline at end of file diff --git a/src/com/learnjava/storage/serializer/JsonStreamSerializer.java b/src/com/learnjava/storage/serializer/JsonStreamSerializer.java index f74d0b6..0c46de5 100644 --- a/src/com/learnjava/storage/serializer/JsonStreamSerializer.java +++ b/src/com/learnjava/storage/serializer/JsonStreamSerializer.java @@ -5,6 +5,7 @@ import java.io.*; import java.nio.charset.StandardCharsets; + public class JsonStreamSerializer implements StreamSerializer { @Override diff --git a/src/com/learnjava/util/JsonParser.java b/src/com/learnjava/util/JsonParser.java index 868c70b..fb7a2f8 100644 --- a/src/com/learnjava/util/JsonParser.java +++ b/src/com/learnjava/util/JsonParser.java @@ -9,8 +9,7 @@ import java.time.LocalDate; public class JsonParser { - - private final static Gson GSON = new GsonBuilder() + private static final Gson GSON = new GsonBuilder() .registerTypeAdapter(Section.class, new JsonSectionAdapter()) .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) .create(); @@ -23,4 +22,15 @@ public static void write(T object, Writer writer) { GSON.toJson(object, writer); } + public static T read(String content, Class clazz) { + return GSON.fromJson(content, clazz); + } + + public static String write(T object) { + return GSON.toJson(object); + } + + public static String write(T object, Class clazz) { + return GSON.toJson(object, clazz); + } } \ No newline at end of file From e275453026f9ef70a88d810ec13da5b4554e5ab3 Mon Sep 17 00:00:00 2001 From: pteryo <116794811+pteryo@users.noreply.github.com> Date: Sun, 20 Aug 2023 14:31:37 +0300 Subject: [PATCH 71/71] =?UTF-8?q?HW15=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D1=81=D0=B5=D1=80=D0=B2=D0=BB=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/learnjava/Config.java | 2 +- src/com/learnjava/storage/SqlStorage.java | 4 +- src/com/learnjava/web/ResumeServlet.java | 64 +++++++++++++++++++++++ web/WEB-INF/web.xml | 16 ++++++ web/css/style.css | 14 +++++ web/index.html | 16 ++++++ web/test.html | 10 ++++ 7 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 src/com/learnjava/web/ResumeServlet.java create mode 100644 web/WEB-INF/web.xml create mode 100644 web/css/style.css create mode 100644 web/index.html create mode 100644 web/test.html diff --git a/src/com/learnjava/Config.java b/src/com/learnjava/Config.java index 74fda2e..51fd4d8 100644 --- a/src/com/learnjava/Config.java +++ b/src/com/learnjava/Config.java @@ -10,7 +10,7 @@ import java.util.Properties; public class Config { - private static final File PROPS = new File("config\\resumes.properties"); + private static final File PROPS = new File("D:\\YandexDisk\\_java_learn\\git\\BaseJava\\config\\resumes.properties"); private static final Config INSTANCE = new Config(); private final File storageDir; diff --git a/src/com/learnjava/storage/SqlStorage.java b/src/com/learnjava/storage/SqlStorage.java index 4e1ec9c..13eabbb 100644 --- a/src/com/learnjava/storage/SqlStorage.java +++ b/src/com/learnjava/storage/SqlStorage.java @@ -192,7 +192,7 @@ private void deleteAttributes(Connection conn, Resume r, String sql) throws SQLE private void addContact(ResultSet rs, Resume r) throws SQLException { String value = rs.getString("value"); if (value != null) { - r.setContact(ContactType.valueOf(rs.getString("type")), value); + r.addContact(ContactType.valueOf(rs.getString("type")), value); } } @@ -200,7 +200,7 @@ private void addSection(ResultSet rs, Resume r) throws SQLException { String content = rs.getString("content"); if (content != null) { SectionType type = SectionType.valueOf(rs.getString("type")); - r.setSection(type, JsonParser.read(content, Section.class)); + r.addSection(type, JsonParser.read(content, Section.class)); } } } \ No newline at end of file diff --git a/src/com/learnjava/web/ResumeServlet.java b/src/com/learnjava/web/ResumeServlet.java new file mode 100644 index 0000000..dd763db --- /dev/null +++ b/src/com/learnjava/web/ResumeServlet.java @@ -0,0 +1,64 @@ +package com.learnjava.web; + +import com.learnjava.Config; +import com.learnjava.model.Resume; +import com.learnjava.storage.Storage; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Writer; + +public class ResumeServlet extends HttpServlet { + + private Storage storage; + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + storage = Config.get().getStorage(); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { + + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { + request.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding("UTF-8"); + response.setContentType("text/html; charset=UTF-8"); + Writer writer = response.getWriter(); + writer.write( + """ + + + + + Список всех резюме + + +
+ + + + + + """); + for (Resume resume : storage.getAllSorted()) { + writer.write( + "\n" + + " \n" + + " \n" + + "\n"); + } + writer.write(""" +
uuidfullName
" + resume.getUuid() + "" + resume.getFullName() + "
+
+ + + """); + } +} \ No newline at end of file diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml new file mode 100644 index 0000000..641774f --- /dev/null +++ b/web/WEB-INF/web.xml @@ -0,0 +1,16 @@ + + + + + resumeServlet + com.learnjava.web.ResumeServlet + + + resumeServlet + /resume + + + \ No newline at end of file diff --git a/web/css/style.css b/web/css/style.css new file mode 100644 index 0000000..b736732 --- /dev/null +++ b/web/css/style.css @@ -0,0 +1,14 @@ +header { + background: none repeat scroll 0 0 #A6C9E2; + color: #2E6E9E; + font-size: 30px; + padding: 5px 20px; +} + +footer { + background: none repeat scroll 0 0 #A6C9E2; + color: #2E6E9E; + font-size: 30px; + padding: 5px 20px; + margin: 20px 0; +} \ No newline at end of file diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..b7726bc --- /dev/null +++ b/web/index.html @@ -0,0 +1,16 @@ + + + + + + Курс JavaSE + Web. + + +
Приложение вебинара Практика Java. Разработка Web + приложения."
+

Курс JavaSE + Web

+

перейти в резюме

+ + + \ No newline at end of file diff --git a/web/test.html b/web/test.html new file mode 100644 index 0000000..abc8808 --- /dev/null +++ b/web/test.html @@ -0,0 +1,10 @@ + + + + + Title + + +Test + + \ No newline at end of file