\immediate\write18{texcount -sum -1 j-spec.tex > /tmp/wordcount.tex}
%\immediate\write18{texcount -sum -1 scenarios/jc-1-c.tex > /tmp/wordcount.tex}
\documentclass[12pt, a4paper]{report}
\usepackage[english,russian]{babel}	% локализация и переносы

\input{main-style-preamble}
\input{fancy-listings-preamble}

\graphicspath{{./pics/}}

\title{Специализация Java}
\author{Иван Игоревич Овчинников}
\date{\today{} (\DTMcurrenttime)}

\usepackage{subfiles}


\begin{document}
\maketitle
\tableofcontents
\pagestyle{plain}

\chapter{Java Core}

\section{Платформа: история и окружение}
\subsection{В этом разделе}
Краткая история (причины возникновения); инструментарий, выбор версии; CLI; структура проекта; документирование;

В этом разделе происходит первое знакомство со внутреннем устройством языка Java и фреймворком разработки приложений с его использованием. Рассматривается примитивный инструментарий и базовые возможности платформы для разработки приложений на языке Java. Разбирается структура проекта, а также происходит ознакомление с базовым инструментарием для разработки на Java. 
\begin{itemize}
\item \nom{JDK}{(от англ. Java Development Kit) — комплект разработчика приложений на языке Java, включающий в себя компилятор, стандартные библиотеки классов, примеры, документацию, различные утилиты и исполнительную систему. В состав JDK не входит интегрированная среда разработки на Java, поэтому разработчик, использующий только JDK, вынужден использовать внешний текстовый редактор и компилировать свои программы, используя утилиты командной строки.}
\item \nom{JRE}{(от англ. Java Runtime Environment) — минимальная (без компилятора и других средств разработки) реализация виртуальной машины, необходимая для исполнения Java-приложений. Состоит из виртуальной машины Java Virtual Machine и библиотеки Java-классов.}
\item \nom{JVM}{(от англ. Java Virtual Machine) — виртуальная машина Java, основная часть исполняющей системы Java. Виртуальная машина Java исполняет байт-код, предварительно созданный из исходного текста Java-программы компилятором. JVM может также использоваться для выполнения программ, написанных на других языках программирования.}
\item \nom{JIT}{(англ. Just-in-Time, компиляция «точно в нужное время»), динамическая компиляция — технология увеличения производительности программных систем, использующих байт-код, путём компиляции байт-кода в машинный код или в другой формат непосредственно во время работы программы. Таким образом достигается высокая скорость выполнения по сравнению с интерпретируемым байт-кодом за счёт увеличения потребления памяти (для хранения результатов компиляции) и затрат времени на компиляцию. Технология JIT базируется на двух более ранних идеях, касающихся среды выполнения: компиляции байт-кода и динамической компиляции.}
\item \nom{CLI}{(англ. Command line interface, Интерфейс командной строки) — разновидность текстового интерфейса между человеком и компьютером, в котором инструкции компьютеру даются в основном путём ввода с клавиатуры текстовых строк (команд). Также известен под названиями «консоль» и «терминал».}
\end{itemize}

\subsection{Краткая история (причины возникновения)}
\begin{itemize}
\item Язык создавали для разработки встраиваемых систем, сетевых приложений и прикладного \nom{ПО}{программное обеспечение};
\item Популярен из-за скорости исполнения и полного абстрагирования от исполнителя кода;
\item Часто используется для программирования бэк-энда веб-приложений из-за изначальной нацеленности на сетевые приложения.
\end{itemize}
\begin{figure}[H]
  \centering
  \includegraphics[width=17cm]{jc-01-tiobe.png}
  \caption{График популярности языков программирования TIOBE}
  \label{pic:java-in-tiobe}
\end{figure}

\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Как Вы думаете, почему язык программирования Java стал популярен в такие короткие сроки?
  \begin{itemize}
  \item существовавшие на тот момент Pascal и C++ были слишком сложными;
  \item Java быстрее C++;
  \item Однажды написанная на Java программа работает везде.
  \end{itemize}
\end{enumerate}

\subsection{Базовый инструментарий, который понадобится (выбор IDE)}
\begin{itemize}
\item NetBeans - хороший, добротный инструмент с лёгким ностальгическим оттенком;
\item Eclipse - для поклонников Eclipse Foundation и швейцарских ножей с полусотней лезвий;
\item IntelliJ IDEA - стандарт де-факто, используется на курсе и в большинстве современных компаний;
\item Android Studio - если заниматься мобильной разработкой.
\end{itemize}

\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Как Вы думаете, почему среда разработки IntelliJ IDEA стала стандартом де-факто в коммерческой разработке приложений на Java?
  \begin{itemize}
  \item NetBeans перестали поддерживать;
  \item Eclipse слишком медленный и тяжеловесный;
  \item IDEA оказалась самой дружелюбной к начинающему программисту;
  \item Все варианты верны.
  \end{itemize}
\end{enumerate}

\subsection{Что нужно скачать, откуда (как выбрать вендора, версии)}
Для разработки понадобится среда разработки (\nom{IDE}{(от англ. Integrated Development Environment) – это интегрированная, единая среда разработки, которая используется разработчиками для создания различного программного обеспечения. IDE представляет собой комплекс из нескольких инструментов, а именно: текстового редактора, компилятора или интерпретатора, средств автоматизации сборки и отладчика.}) и инструментарий разработчика (JDK). JDK выпускается несколькими поставщиками, большинство из них бесплатны и полнофункциональны, то есть поддерживают весь функционал языка и платформы.

В последнее время, с развитием контейнеризации приложений, часто устанавливают инструментарий в Docker-контейнер и ведут разработку прямо в контейнере, это позволяет не захламлять компьютер разработчика разными версиями инструментария и быстро разворачивать свои приложения в \nom{CI}{(англ. Continious Integration) практика разработки программного обеспечения, которая заключается в постоянном слиянии рабочих копий в общую основную ветвь разработки и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем.} или на целевом сервере.
\begin{frm}
  В общем случае, для разработки на любом языке программирования нужны так называемые \nom{SDK}{(от англ. software development kit, комплект для разработки программного обеспечения) — это набор инструментов для разработки программного обеспечения в одном устанавливаемом пакете. Они облегчают создание приложений, имея компилятор, отладчик и иногда программную среду. В основном они зависят от комбинации аппаратной платформы компьютера и операционной системы.} (Software Development Kit, англ. - инструментарий разработчика приложений или инструментарий для разработки приложений). Частный случай такого SDK - инструментарий разработчика на языке Java - Java Development Kit.
\end{frm}
На курсе будет использоваться BellSoft Liberica JDK 11, но возможно использовать и других производителей, например, самую распространённую Oracle JDK. Производителя следует выбирать из требований по лицензированию, так, например, Oracle JDK можно использовать бесплатно только в личных целях, за коммерческую разработку с использованием этого инструментария придётся заплатить.

\begin{frm}
  Для корректной работы самого инструментария и сторонних приложений, использующих инструментарий, проследите, пожалуйста, что установлены следующие переменные среды ОС:
  \begin{itemize}
  \item в системную \code{PATH} добавить путь до исполняемых файлов JDK, например, для UNIX-подобных систем: \verb|PATH=$PATH:/usr/lib/jvm/jdk1.8.0_221/bin|
  \item \code{JAVA_HOME} путь до корня JDK, например, для UNIX-подобных систем: \code{JAVA_HOME=/usr/lib/jvm/jdk1.8.0_221/}
  \item \code{JRE_HOME} путь до файлов JRE из состава установленной JDK, например, для UNIX-подобных систем: \code{JRE_HOME=/usr/lib/jvm/jdk1.8.0_221/jre/}
  \item \code{J2SDKDIR} устаревшая переменная для JDK, используется некоторыми старыми приложениями, например, для UNIX-подобных систем: \code{J2SDKDIR=/usr/lib/jvm/jdk1.8.0_221/}
  \item \code{J2REDIR} устаревшая переменная для JRE, используется некоторыми старыми приложениями, например, для UNIX-подобных систем: \code{J2REDIR=/usr/lib/jvm/jdk1.8.0_221/jre/}
  \end{itemize}
\end{frm}

Также возможно использовать и другие версии, но не старше 1.8. Это обосновано тем, что основные разработки на данный момент только начинают обновлять инструментарий до более новых версий (часто 11 или 13) или вовсе переходят на другие JVM-языки, такие как Scala, Groovy или Kotlin.

Для решения некоторых несложных задач курса мы будем писать простые приложения, не содержащие ООП, сложных взаимосвязей и проверок, в этом случае нам понадобится Jupyter notebook с установленным ядром (kernel) IJava.

\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Чем отличается SDK от JDK?
\item Какая версия языка (к сожалению) остаётся самой популярной в разработке на Java?
\item Какие ещё JVM языки существуют?
\end{enumerate}

\subsection{Из чего всё состоит (JDK, JRE, JVM и их друзья)}
TL;DR:
\begin{itemize}
\item JDK = JRE + инструменты разработчика; 
\item JRE = JVM + библиотеки классов; 
\item JVM = Native API + механизм исполнения + управление памятью.
\end{itemize}

Как именно всё работает? Если коротко, то слой за слоем накладывая абстракции. Программы на любом языке программирования исполняются на компьютере, то есть, так или иначе, задействуют процессор, оперативную память и прочие аппаратурные компоненты. Эти аппаратурные компоненты предоставляют для доступа к себе низкоуровневые интерфейсы, которые задействует операционная система, предоставляя в свою очередь интерфейс чуть проще программам, взаимодействующим с ней. Этот интерфейс взаимодействия с \nom{ОС}{(операционная система) — комплекс управляющих и обрабатывающих программ, которые, с одной стороны, выступают как интерфейс между устройствами вычислительной системы и прикладными программами, а с другой стороны — предназначены для управления устройствами, управления вычислительными процессами, эффективного распределения вычислительных ресурсов между вычислительными процессами и организации надёжных вычислений.} мы для простоты будем называть Native API.

С ОС взаимодействует JVM (\href{https://ru.m.wikipedia.org/wiki/Список_виртуальных_машин_Java}{Wikipedia: Список виртуальных машин Java}), то есть, используя Native API, нам становится всё равно, какая именно ОС установлена на компьютере, главное уметь выполняться на JVM. Это открывает простор для создания целой группы языков, они носят общее бытовое название JVM-языки, к ним относят Scala, Groovy, Kotlin и другие. Внутри JVM осуществляется управление памятью, существует механизм исполнения программ, специальный JIT\footnote{JIT, just-in-time - англ. в\'{о}время, прямо сейчас}-компилятор, генерирующий платформенно-зависимый код.

JVM для своей работы запрашивает у ОС некоторый сегмент оперативной памяти, в котором хранит данные программы. Это хранение происходит «слоями»:
\begin{enumerate}
\item Eden Space (heap) – в этой области выделяется память под все создаваемые из программы объекты. Большая часть объектов живёт недолго (итераторы, временные объекты, используемые внутри методов и т.п.), и удаляются при выполнении сборок мусора это области памяти, не перемещаются в другие области памяти. Когда данная область заполняется (т.е. количество выделенной памяти в этой области превышает некоторый заданный процент), сборщик мусора выполняет быструю (minor collection) сборку. По сравнению с полной сборкой, она занимает мало времени, и затрагивает только эту область памяти, а именно, очищает от устаревших объектов Eden Space и перемещает выжившие объекты в следующую область.
\item Survivor Space (heap) – сюда перемещаются объекты из предыдущей области после того, как они пережили хотя бы одну сборку мусора. Время от времени долгоживущие объекты из этой области перемещаются в Tenured Space.
\item Tenured (Old) Generation (heap) — Здесь скапливаются долгоживущие объекты (крупные высокоуровневые объекты, синглтоны, менеджеры ресурсов и прочие). Когда заполняется эта область, выполняется полная сборка мусора (full, major collection), которая обрабатывает все созданные JVM объекты.
\item Permanent Generation (non-heap) – Здесь хранится метаинформация, используемая JVM (используемые классы, методы и т.п.).
\item Code Cache (non-heap) — эта область используется JVM, когда включена JIT-компиляция, в ней кешируется скомпилированный платформенно-зависимый код.
\end{enumerate}

JVM самостоятельно осуществляет сборку так называемого мусора, что значительно облегчает работу программиста по отслеживанию утечек памяти, но важно помнить, что в Java утечки памяти всё равно существуют, особенно при программировании многопоточных приложений. 

\begin{figure}[H]
  \centering
  \def\svgwidth{150mm}
  \input{pics/jc-01-jvm-struct.pdf_tex}
  \label{jvm:structure}
  \caption{принцип работы JVM}
\end{figure}

На пользовательском уровне важно не только исполнять базовые инструкции программы, но чтобы эти базовые инструкции умели как-то взаимодействовать со внешним миром, в том числе другими программами, поэтому JVM интегрирована в JRE - Java Runtime Environment. JRE - это набор из классов и интерфейсов, реализующих
\begin{itemize}
\item возможности сетевого взаимодействия;
\item рисование графики и графический пользовательский интерфейс;
\item мультимедиа;
\item математический аппарат;
\item наследование и полиморфизм;
\item рефлексию;
\item ... многое другое.
\end{itemize}

Java Development Kit является изрядно дополненным специальными Java приложениями SDK. JDK дополняет JRE не только утилитами для компиляции, но и утилитами для создания документации, отладки, развёртывания приложений и многими другими. В таблице \ref{table:jdk-contents} на странице \pageref{table:jdk-contents}, приведена примерная структура и состав JDK и JRE, а также указаны их основные и наиболее часто используемые компоненты из состава Java Standard Edition. Помимо стандартной редакции существует и Enterprise Edition, содержащий компоненты для создания веб-приложений, но JEE активно вытесняется фреймворками Spring и Spring Boot.

\begin{table}[H]
  \centering
\begin{adjustbox}{angle=90}
\begin{tabular}{|l|ll|llllllll|}
\cline{1-1} \cline{4-11}
\multirow{15}{*}{\rotatebox[origin=c]{270}{Java Development Kit }} &                           &  & \multicolumn{8}{l|}{Language}                                                                                                                                                                                                                                                                             \\ \cline{4-11} 
 &                        &                                                                       & \multicolumn{1}{l|}{\multirow{3}{23mm}{tools + tools api}}            & \multicolumn{1}{l|}{javac}     & \multicolumn{1}{l|}{java}                & \multicolumn{1}{l|}{javadoc}  & \multicolumn{1}{l|}{javap}        & \multicolumn{1}{l|}{jar}       & \multicolumn{2}{l|}{JPDA}                        \\ \cline{5-11} 
 &                        &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{1}{l|}{JConsole}  & \multicolumn{1}{p{23mm}|}{JavaVisualVM}  & \multicolumn{1}{l|}{JMC}      & \multicolumn{1}{l|}{JFR}          & \multicolumn{1}{l|}{Java DB}   & \multicolumn{1}{l|}{Int'l}         & JVM TI      \\ \cline{5-11} 
 &                        &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{1}{l|}{IDL}       & \multicolumn{1}{l|}{Troubleshoot}        & \multicolumn{1}{l|}{Security} & \multicolumn{1}{l|}{RMI}          & \multicolumn{1}{l|}{Scripting} & \multicolumn{1}{l|}{Web services}  & Deploy      \\ \cline{2-2} \cline{4-11} 
 & \multicolumn{1}{l|}{\multirow{11}{*}{\rotatebox[origin=c]{270}{Java Runtime Environment }}} &  & \multicolumn{1}{l|}{deployment}                                       & \multicolumn{4}{l|}{Java Web}                                                                                                                 & \multicolumn{3}{l|}{Applet/Java plug-in}                                          \\ \cline{3-11} 
 & \multicolumn{1}{l|}{}  & \multirow{10}{*}{\rotatebox[origin=c]{270}{Java Standard Edition }}   & \multicolumn{1}{l|}{\multirow{2}{*}{UI toolkit}}                      & \multicolumn{2}{l|}{Swing}                                                & \multicolumn{2}{l|}{Java 2D}                                      & \multicolumn{1}{l|}{AWT}       & \multicolumn{2}{l|}{Accessibility}               \\ \cline{5-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{2}{l|}{Drag'n'Drop}                                          & \multicolumn{2}{l|}{Input Methods}                                & \multicolumn{1}{l|}{Image I/O} & \multicolumn{1}{l|}{Print Service} & Sound       \\ \cline{4-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{p{23mm}|}{Integration libraries}                      & \multicolumn{1}{l|}{IDL}       & \multicolumn{1}{l|}{JDBC}                & \multicolumn{1}{l|}{JNDI}     & \multicolumn{1}{l|}{RMI}          & \multicolumn{1}{l|}{RMI-IIOP}  & \multicolumn{2}{l|}{Scripting}                   \\ \cline{4-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{\multirow{3}{23mm}{Other base libraries}}         & \multicolumn{2}{l|}{Override Mechanism}                                   & \multicolumn{2}{l|}{Intl Support}                                 & \multicolumn{2}{l|}{Input/Output}                                   & JMX         \\ \cline{5-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{2}{l|}{XML JAXP}                                             & \multicolumn{2}{l|}{Math}                                         & \multicolumn{2}{l|}{Networking}                                     & Beans       \\ \cline{5-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{2}{l|}{Security}                                             & \multicolumn{2}{l|}{Serialization}                                & \multicolumn{2}{l|}{Extension Mechanism}                            & JNI         \\ \cline{4-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{\multirow{3}{23mm}{Java lang and util base libs}} & \multicolumn{1}{l|}{JAR}       & \multicolumn{1}{l|}{Lang and util}       & \multicolumn{2}{l|}{Ref Objects}                                  & \multicolumn{2}{l|}{Preference API}                                 & Reflection  \\ \cline{5-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{1}{l|}{Zip}       & \multicolumn{1}{l|}{Management}          & \multicolumn{2}{l|}{Instrumentation}                              & \multicolumn{2}{l|}{Stream API}                                     & Collections \\ \cline{5-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{}                                                 & \multicolumn{1}{l|}{Logging}   & \multicolumn{1}{p{23mm}|}{Regular Expressions} & \multicolumn{2}{p{23mm}|}{Concurrency Utilities}            & \multicolumn{2}{l|}{Datetime}                                       & Versioning  \\ \cline{4-11} 
 & \multicolumn{1}{l|}{}  &                                                                       & \multicolumn{1}{l|}{JVM}                                              & \multicolumn{7}{l|}{Java Hot Spot VM (JIT)}                                                                                                                                                                                       \\ \hline
\end{tabular}
\end{adjustbox}
\label{table:jdk-contents}
\caption{Общее представление состава JDK}
\end{table}

\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item JVM и JRE - это одно и тоже?
\item Что входит в состав JDK, но не входят в состав JRE?
\item Утечки памяти
  \begin{itemize}
  \item Невозможны, поскольку работает сборщик мусора;
  \item Возможны;
  \item Существуют только в С++ и других языках с открытым менеджментом памяти.
  \end{itemize}
\end{enumerate}

\subsection{Структура проекта (пакеты, классы, метод main, комментарии)}
Проекты могут быть любой сложности. Часто структуру проекта задаёт сборщик проекта, предписывая в каких папках будут храниться исходные коды, исполняемые файлы, ресурсы и документация. Без их использования необходимо задать структуру самостоятельно.

\textbf{Простейший проект} чаще всего состоит из одного файла исходного кода, который возможно скомпилировать и запустить как самостоятельный объект. Отличительная особенность в том, что чаще всего это один или несколько статических методов в одном классе.

Файл \code{Main.java} в этом случае может иметь следующий, минималистичный вид
\begin{lstlisting}[language=Java,style=JCodeStyle]
public class Main { 
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}
\end{lstlisting}

\textbf{Скриптовый проект} это достаточно новый тип проектов, он получил развитие благодаря растущей популярности Jupyter Notebook. Скриптовые проекты удобны, когда нужно отработать какую-то небольшую функциональность или пошагово пояснить работу какого-то алгоритма.
\begin{figure}[H]
  \centering
  \includegraphics[width=12cm]{jc-01-jupyter-example.png}
  \caption{Пример простого Java проекта в Jupyter Notebook}
  \label{pic:jupyter-sample}
\end{figure}

\textbf{Обычный проект} состоит из пакетов, которые содержат классы, которые в свою очередь как-то связаны между собой и содержат код, который исполняется.
\begin{itemize}
\item Пакеты. Пакеты объединяют классы по смыслу. Классы, находящиеся в одном пакете доступны друг другу даже если находятся в разных проектах. У пакетов есть правила именования: обычно это обратное доменное имя (например, для gb.ru это будет ru.gb), название проекта, и далее уже внутренняя структура. Пакеты именуют строчными латинскими буквами. Чтобы явно отнести класс к пакету, нужно прописать в классе название пакета после оператора \code{package}.
\item Классы. Основная единица исходного кода программы. Одному файлу следует сопоставлять один класс. Название класса - это имя существительное в именительном падеже, написанное с заглавной буквы. Если требуется назвать класс в несколько слов, применяют UpperCamelCase.
\item \code{public static void main(String[] args)}. Метод, который является точкой входа в программу. Должен находиться в публичном классе. При создании этого метода важно полностью повторить его сигнатуру и обязательно написать его с название со строчной буквы.
\item Комментарии. Это часть кода, которую игнорирует компилятор при преобразовании исходного кода. Комментарии бывают:
  \begin{itemize}
  \item \code{// comment} - до конца строки. Самый простой и самый часто используемый комментарий.
  \item \code{/* comment */} - внутристрочный или многострочный. Никогда не используйте его внутри строк, несмотря на то, что это возможно.
  \item \code{/** comment */} - комментарий-документация. Многострочный. Из него утилитой Javadoc создаётся веб-страница с комментарием.
  \end{itemize}
\end{itemize}

Для примера был создан проект, содержащий два класса, находящихся в разных пакетах. Дерево проекта представлено на рис. \hrf{pic:simple-tree}, где папка с выходными (скомпилированными) бинарными файлами пуста, а файл README.md создан для лучшей демонстрации корня проекта.

\begin{figure}[H]
  \begin{forest}
    for tree={
      font=\ttfamily, grow'=0, child anchor=west,
      parent anchor=south, anchor=west, calign=first,
      edge path={
        \noexpand\path [draw, \forestoption{edge}]
        (!u.south west) +(7.5pt,0) |- node[fill,inner sep=1.25pt]
        {} (.child anchor)\forestoption{edge label};
      }, before typesetting nodes={
        if n=1 {insert before={[,phantom]}} {} },
      fit=band, before computing xy={l=15pt},
    }
    [Sample
     [src
      [ru
       [gb
        [jcore
         [regular
          [OtherClass.java]
         ]
         [sample
          [Main.java]
         ]
        ]
       ]
      ]
     ]
     [out
     ]
     [README.md]
    ]
  \end{forest}
  \label{pic:simple-tree}
  \caption{Структура простого проекта}
\end{figure}

Содержимое файлов исходного кода представлено ниже.
\begin{lstlisting}[language=Java,style=JCodeStyle]
package ru.gb.jcore.sample;

import ru.gb.jcore.regular.OtherClass;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, world!"); // greetings
        int result = OtherClass.sum(2, 2);   // using a class from other package
        System.out.println(OtherClass.decorate(result));
    }
}
\end{lstlisting}
\begin{lstlisting}[language=Java,style=JCodeStyle]
package ru.gb.jcore.regular;

public class OtherClass {
    public static int sum(int a, int b) {
        return a + b; // return without overflow check
    }

    public static String decorate(int a) {
        return String.format("Here is your number: %d.", a);
    }
}
\end{lstlisting}

\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Зачем складывать классы в пакеты?
\item Может ли существовать класс вне пакета?
\item Комментирование кода
  \begin{itemize}
  \item Нужно только если пишется большая подключаемая библиотека;
  \item Хорошая привычка;
  \item Захламляет исходники.
  \end{itemize}
\end{enumerate}

\subsection{Отложим мышки в сторону (CLI: сборка, пакеты, запуск)}
Простейший проект возможно скомпилировать и запустить без использования тяжеловесных сред разработки, введя в командной строке ОС две команды:
\begin{itemize}
\item javac <Name.java> скомпилирует файл исходников и создаст в этой же папке файл с байт-кодом;
\item java Name запустит скомпилированный класс (из файла с расширением \code{.class}).
\end{itemize}

\begin{lstlisting}[style=ASMStyle]
ivan-igorevich@gb sources % ls
Main.java
ivan-igorevich@gb sources % javac Main.java 
ivan-igorevich@gb sources % ls
Main.class	Main.java
ivan-igorevich@gb sources % java Main        
Hello, world!
\end{lstlisting}

\begin{frm}
  Скомпилированные классы всегда содержат одинаковые первые четыре байта, которые в шестнадцатиричном представлении формируют надпись «кофе, крошка».
\begin{figure}[H]
  \centering
  \includegraphics[width=14cm]{jc-01-cafe-babe.png}
\end{figure}
\end{frm}

Для компиляции более сложных проектов, необходимо указать компилятору, откуда забирать файлы исходников и куда складывать готовые файлы классов, а интерпретатору, откуда забирать файлы скомпилированных классов. Для этого существуют следующие ключи:
\begin{itemize}
\item javac:
  \begin{itemize}
  \item \code{-d} выходная папка (директория) назначения;
  \item \code{-sourcepath} папка с исходниками проекта;
  \end{itemize}
\item java:
  \begin{itemize}
  \item \code{-classpath} папка с классами проекта;
  \end{itemize}
\end{itemize}

Классы проекта компилируются в выходную папку с сохранением иерархии пакетов.

\begin{lstlisting}[style=ASMStyle]
ivan-igorevich@gb Sample % javac -sourcepath ./src -d out src/ru/gb/jcore/sample/Main.java
ivan-igorevich@gb Sample % java -classpath ./out ru.gb.jcore.sample.Main
Hello, world!
Here is your number: 4.
\end{lstlisting}

\subsubsection{Задания для самопроверки}
\begin{enumerate}
\item Что такое javac?
\item Кофе, крошка?
\item Где находится класс в папке назначения работы компилятора?
  \begin{itemize}
  \item В подпапках, повторяющих структуру пакетов в исходниках
  \item В корне плоским списком;
  \item Зависит от ключей компиляции.
  \end{itemize}
\end{enumerate}

\subsection{Документирование (Javadoc)}
Документирование конкретных методов и классов всегда ложится на плечи программиста, потому что никто не знает программу и алгоритмы в ней лучше, чем программист. Утилита Javadoc избавляет программиста от необходимости осваивать инструменты создания веб-страниц и записывать туда свою документацию. Достаточно писать хорошо отформатированные комментарии, а остальное Javadoc возьмёт на себя.
\begin{figure}[H]
  \centering
  \includegraphics[width=12cm]{jc-01-javadoc.png}
  \caption{Часть cтраницы автосгенерированной документации}
  \label{pic:}
\end{figure}

Чтобы просто создать документацию надо вызвать утилиту javadoc с набором ключей.
\begin{itemize}
  \item \code{ru} пакет, для которого нужно создать документацию;
  \item \code{-d} папка (или директория) назначения;
  \item \code{-sourcepath} папка с исходниками проекта;
  \item \code{-cp} путь до скомпилированных классов;
  \item \code{-subpackages} нужно ли заглядывать в пакеты-с-пакетами;
\end{itemize}
    
Часто необходимо указать, в какой кодировке записан файл исходных кодов, и в какой кодировке должна быть выполнена документация (например, файлы исходников на языке Java всегда сохраняются в кодировке \nom{UTF-8}{(от англ. Unicode Transformation Format, 8-bit — «формат преобразования Юникода, 8-бит») — распространённый стандарт кодирования символов, позволяющий более компактно хранить и передавать символы Юникода, используя переменное количество байт (от 1 до 4), и обеспечивающий полную обратную совместимость с 7-битной кодировкой ASCII. Кодировка UTF-8 сейчас является доминирующей в веб-пространстве. Она также нашла широкое применение в UNIX-подобных операционных системах.}, а основная кодировка для ОС Windows - \nom{cp1251}{набор символов и кодировка, являющаяся стандартной 8-битной кодировкой для русских версий Microsoft Windows до 10-й версии. Была создана на базе кодировок, использовавшихся в ранних русификаторах Windows.})
\begin{itemize}
  \item \code{-locale ru_RU} язык документации (для правильной расстановки переносов и разделяющих знаков);
  \item \code{-encoding} кодировка исходных текстов программы;
  \item \code{-docencoding} кодировка конечной сгенерированной документации.
\end{itemize}

Чаще всего в комментариях используются следующие ключевые слова:
\begin{itemize}
\item \code{@param} описание входящих параметров
\item \code{@throws} выбрасываемые исключения
\item \code{@return} описание возвращаемого значения
\item \code{@see} где ещё можно почитать по теме
\item \code{@since} с какой версии продукта доступен метод
\item \code{{@code "public"}} вставка кода в описание
\end{itemize}

\subsection*{Домашнее задание}
\begin{itemize}
\item Создать проект из трёх классов (основной с точкой входа и два класса в другом пакете), которые вместе должны составлять одну программу, позволяющую производить четыре основных математических действия и осуществлять форматированный вывод результатов пользователю. 
\item Скомпилировать проект, а также создать для этого проекта стандартную веб-страницу с документацией ко всем пакетам.
\end{itemize}

\section{Управление проектом: сборщики проектов}
Управление проектом: Jar-файлы; Gradle/Maven: зависимости, выгрузка артефакта, публичные репозитории, свойства проекта, приватные репозитории (хостинг); Bazel
\subsection*{Задания к семинару}
\begin{itemize}
\item Создать загружаемый артефакт с функцией суммирования двух чисел и загрузить его в локальный кэш артефактов;
\end{itemize}

\section{Специализация: данные и функции}
Базовые функции языка: математические операторы, условия, циклы, бинарные операторы; Данные: типы, преобразование типов, константы и переменные (примитивные, ссылочные), бинарное представление, массивы (ссылочная природа массивов, индексация, манипуляция данными); Функции: параметры, возвращаемые значения, перегрузка функций;
\subsection{Данные}
Хранение данных в Java осуществляется привычным для программиста образом: в переменных и константах. Языки‌ ‌программирования‌ ‌бывают‌ ‌типизированными‌ ‌и‌ ‌нетипизированными‌ ‌(бестиповыми).‌ ‌

Отсутствие типизации ‌в основном присуще старым и низкоуровневым языкам программирования, например, ‌Forth, некоторые ассемблеры. ‌Все данные в таких языках считаются цепочками бит произвольной длины и, как следует из названия, не делятся на типы. Работа с ними часто труднее, и при чтении кода не всегда ясно, о каком типе переменной идет речь. При этом часто безтиповые языки работают быстрее типизированных, но описывать с их помощью большие проекты со сложными взаимосвязями довольно утомительно.
\begin{frm}
 Java является языком со строгой (сильной) явной статической типизацией.  
\end{frm}
Что это значит?
\begin{itemize}
\item Статическая - у каждой переменной должен быть тип и мы этот тип поменять не можем. Этому свойству противопоставляется динамическая типизация;
\item Явная - при создании переменной мы должны ей обязательно присвоить какой-то тип, явно написав это в коде. Бывают языки с неявной типизацией, например, Python;
\item Строгая(сильная) - невозможно смешивать разнотипные данные. С другой стороны, существует JavaScript, в котором запись \code{2 + true} выдаст результат \code{3}.
\end{itemize}

Все данные в Java делятся на две основные категории: примитивные и ссылочные. 

Данные: типы, преобразование типов, константы и переменные (примитивные, ссылочные), бинарное представление, массивы (ссылочная природа массивов, индексация, манипуляция данными);

\begin{figure}[H]
    \centering
    \begin{tabular}{|p{17mm}|p{80mm}|p{55mm}|}
        \hline
        Тип & Пояснение & Диапазон \\
        \hline
        byte & Самый маленький из адресуемых типов, 8 бит, знаковый & [\textminus128, +127] \\
        \hline
        short & Тип короткого целого числа, 16 бит, знаковый & [\textminus32 768, +32 767]\\
        \hline
        char & Целочисленный тип для хранения символов в кодировке UTF-8, 16 бит, беззнаковый & [0, +65 535]\\
        \hline
        int & Основной тип целого числа, 32 бита, знаковый & [\textminus2 147 483 648, +2 147 483 647] \\
        \hline
        long & Тип длинного целого числа, 64 бита, знаковый & [\textminus9 223 372 036 854 775 808, +9 223 372 036 854 775 807] \\
        \hline
        float & Тип вещественного числа с плавающей запятой (одинарной точности, 32 бита) &  \\
        \hline
        double & Тип вещественного числа с плавающей запятой (двойной точности, 64 бита) &  \\
        \hline
        boolean & Логический тип данных & true, false \\
        \hline
    \end{tabular}
    \caption{Основные типы данных в языке С}
    \label{tab:types}
\end{figure}

Базовые функции языка: математические операторы, условия, циклы, бинарные операторы;

Функции: параметры, возвращаемые значения, перегрузка функций;



\subsubsection{Антипаттерн "магические числа"}
В прошлом примере мы использовали антипаттерн - плохой стиль для написания кода. Число 18 используется в коде коде без пояснений. Такой антипаттерн называется "магическое число". Рекомендуется помещать числа в константы, которые храняться в начале файла.
ADULT = 18
age = float(input('Ваш возраст: '))
how\_old = age - ADULT
print(how\_old, "лет назад ты стал совершеннолетним")

Плюсом такого подхода является возможность легко корректировать большие проекты. Представьте, что в вашем коде несколько тысяч строк, а число 18 использовалось несколько десятков раз. 
●	При развертывании проекта в стране, где совершеннолетием считается 21 год вы будете перечитывать весь код в поисках магических "18" и править их на "21". В случае с константой изменить число нужно в одном месте.
●	Дополнительный сложности могут возникнуть, если в коде будет 18 как возраст совершеннолетия и 18 как коэффициент для рассчёт чего-либо. Теперь править кода ещё сложнее, ведь возраст изменился, а коэффициент -нет. В случае с сохранением значений в константы мы снова меняем число в одном месте.

\subsection*{Задания к семинару}
\begin{itemize}
\item Написать как можно больше вариантов функции инвертирования массива единиц и нулей за 15 минут (без ветвлений любого рода);
\item Сравнить без условий две даты, представленные в виде трёх чисел гггг-мм-дд;
\end{itemize}

\section{Специализация: ООП}
Инкапсуляция: Классы и объекты (внутренние классы, вложенные классы, static, private/public, final, интерфейс взаимодействия с объектом), перечисления (создание, конструкторы перечислений, объекты перечислений, дополнительные свойства); Наследование: extends, Object (глобальное наследование), protected, преобразование типов, final; Полиморфизм: override, abstract, final;
%\subfile{scenarios/jc-4}

\section{Специализация: Тонкости работы}
Файловая система и представление данных; Пакеты \code{java.io}, \code{java.nio}, \code{String}, \code{StringBuilder}, string pool, ?JSON/XML?


  
\chapter{Java Development Kit}
\section{Исключения}
Механизм и понятие, введение в \textbf{многопоточность}, throw; Наследование и полиморфизм в исключениях; Способы обработки исключений (try/catch, throws, finally); try-with-resources, штатные и нештатные ситуации

\section{Интерфейсы}
Понятие и принцип работы, implements; Наследование и множественное наследование интерфейсов; Значения по-умолчанию

\section{Обобщённое программирование}

\section{Коллекции}
List, Set; Хэш-код, интерфейс Comparable; Map, Object (Использование методов, Переопределение методов); Итераторы, \textbf{Многопоточные} коллекции

\section{Многопоточность}
Понятие, Принцип (реальная и псевдопараллельность); Runnable, Thread (Свойства, Особенности создания); Deadlock, Состояние гонки, Object (Ожидание/уведомление); Синхронизация (Синхронизация по монитору, Частичная, по классу)

\section{Графический интерфейс пользователя}
GUI (Swing): Окна и свойства окон, \textbf{Многопоточность} и абстргирование асинхронных вызовов; менеджеры размещений и проведение параллелей с веб-фреймворками, разделение на фронт-энд и бэк-энд; JPanel и рисование, Обработка действий пользователя


\chapter{Java Junior}
\section{JDBC}

\section{Сетевое программирование}
Socket, ServerSocket, Многопоточность, абстрагирование сетевого взаимодействия, интерфейсы

\section{Введение в архитектуры приложений на Java}
клиент-серверы, веб-приложения, сервлеты, толстые и тонкие клиенты, выделение бизнес-логики и хранения, создание общих пространств и модульность проекта

\section{Сериализация, StreamAPI, ReflectionAPI}

\section{Введение в Java EE}

\section{Введение в Spring framework}


\chapter{Java Junior+}


\newpage
\appendix
\sloppy
\addcontentsline{toc}{chapter}{Термины, определения и сокращения}
\printnomenclature[20mm]

\chapter*{Приложения}
\addcontentsline{toc}{chapter}{Приложения}
\renewcommand{\thesection}{\Asbuk{section}}



\end{document}

