diff --git a/build/j-spec.pdf b/build/j-spec.pdf index e6ca3ba..e10de81 100644 Binary files a/build/j-spec.pdf and b/build/j-spec.pdf differ diff --git a/j-spec.tex b/j-spec.tex index 4a4ce35..8801bb6 100644 --- a/j-spec.tex +++ b/j-spec.tex @@ -18,82 +18,14 @@ \tableofcontents \pagestyle{plain} -\newpage %\chapter{Java Core} +\newpage \subfile{jtc1-01a} \newpage +\subfile{jtc2-02a} +\newpage \subfile{jtd6-11a} -\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} diff --git a/pics/jc-02-float01.png b/pics/jc-02-float01.png new file mode 100644 index 0000000..2db4f4d Binary files /dev/null and b/pics/jc-02-float01.png differ diff --git a/pics/jc-02-float02.png b/pics/jc-02-float02.png new file mode 100644 index 0000000..22f112b Binary files /dev/null and b/pics/jc-02-float02.png differ diff --git a/pics/jc-02-float03.png b/pics/jc-02-float03.png new file mode 100644 index 0000000..fb10edc Binary files /dev/null and b/pics/jc-02-float03.png differ diff --git a/scenarios/build/jtc2-02b.pdf b/scenarios/build/jtc2-02b.pdf index 9039d97..764e2a5 100644 Binary files a/scenarios/build/jtc2-02b.pdf and b/scenarios/build/jtc2-02b.pdf differ diff --git a/scenarios/jtc2-02b.tex b/scenarios/jtc2-02b.tex index 5f4fe84..36aee53 100644 --- a/scenarios/jtc2-02b.tex +++ b/scenarios/jtc2-02b.tex @@ -113,7 +113,16 @@ Java является языком со \textbf{строгой} (также мо \begin{frame} \frametitle{Типы, преобразование типов} - целые числа + Бинарное (битовое) представление +\end{frame} +\note{ + При разговоре о переполнении нельзя не упомянуть о том, что же именно переполняется. поговорим о единичках и ноликах. Важно помнить, что все компьютеры так или иначе работают от электричества и являются довольно примитивными по сути устройствами, которые понимают только два состояния: есть напряжение в цепи или нет. +} + +\begin{frame} + \frametitle{Типы, преобразование типов} + таблица из методички «Основные типы данных в языке Java» + целочисленные типы \end{frame} \note{ целочисленных типов аж 4 и они занимают 1,2,4,8 байт соответственно. про чар, несмотря на то, что он целочисленный мы поговорим чуть позднее. с четырьмя основными целочисленными типами всё просто - значения в них могут быть только целые, никак и никогда невозможно присвоить им дробных значений, хотя и тут можно сделать оговорку и поклон в сторону арифметики с фиксированной запятой, но мы этого делать не будем, чтобы не взрывать себе мозг и не сбиваться с основной мысли. итак, целочисленные типы с диапазонами @@ -131,27 +140,134 @@ Java является языком со \textbf{строгой} (также мо } \newpage \note{ - Я вот сказал, что инт самый часто используемый и внезапно подумал: а ведь чаще всего было бы достаточно шорта, например, в циклах, итерирующихся по массивам, или во временных хранениях значений, скажем, возраста человека, но всё равно все по привычке используют инт. + Я вот сказал, что инт самый часто используемый и внезапно подумал: а ведь чаще всего было бы достаточно шорта, например, в циклах, итерирующихся по подавляющему большинству коллекций, или при хранении значений, скажем, возраста человека, но всё равно все по привычке используют инт. - далее - лайвкод в котором нужно показать присвоение к байту и попытку присвоения лонга, показать предупреждения среды. + далее - лайвкод в котором нужно показать присвоение к байту без переполнения и попытку присвоения лонга, показать предупреждения среды. - как мы видим, к маленькому байту вполне успешно присваивается инт. получается, обманул, сказав, что все числа это инты? давайте посмотрим на следующий пример - попытку присвоить значение 5 млрд переменной типа лонг. помним, что в лонге можно хранить очень большие числа, но среда показывает ошибку, значит и тут наврал? давайте разбираться по порядку: если мы посмотрим на ошибку, там английскими буквами будет очень понятно написано - не могу положить такое большое значение в переменную типа инт. а это может значить только одно: справа - инт. не соврал. + как мы видим, к маленькому байту вполне успешно присваивается инт. получается, обманул, сказав, что все числа это инты? давайте посмотрим на следующий пример - попытку присвоить значение 5 млрд переменной типа лонг. помним, что в лонге можно хранить очень большие числа, но среда показывает ошибку, значит и тут наврал? давайте разбираться по порядку: если мы посмотрим на ошибку, там английскими буквами будет очень понятно написано - не могу положить такое большое значение в переменную типа инт. а это может значить только одно: справа - инт. не соврал. Почему большой инт без проблем присваивается к маленькому байту поговорм буквально через несколько минут, пока просто запомним, что это происходит. +} + +\begin{frame} + \frametitle{Типы, преобразование типов} +таблица из методички «Основные типы данных в языке Java» +\end{frame} +\note{ + Далее речь пойдёт о том, что называется числами с плавающей запятой. в англоязычной литературе эти числа называются числа с плавающей точкой (от английского флоутин поинт), такое различие связано с тем, что в русскоязычной литературе принято отделять дробную часть числа запятой, а в европейской и американской - точкой. + + Как мы видим, два из восьми типов не имеют диапазонов значений, это связано с тем, что диапазоны значений флоута и дабла заключаются не в величине возможных хранимых чисел, а в точности этих чисел после запятой. до какого знака будет сохранена точность. Говорить о числах с плавающей точкой и ничего не сказать об особенности их хранения - преступление, поэтому, отвлечёмся. } \begin{frame} \frametitle{Типы, преобразование типов} немного о хранении чисел с плавающей точкой + много хорошо и подробно, но на С https://habr.com/ru/post/112953/ + \includegraphics[width=100mm]{../pics/jc-02-float01.png} \end{frame} \note{ - Диапазоны значений флоута и дабла заключаются не в величине возможных хранимых чисел, а в точности этих чисел после запятой. до какого знака будет сохранена точность. +Работает по стандарту IEEE 754 (1985). Для работы с числами с плавающей запятой на аппаратурном уровне к обычному процессору который находится в вашем устройстве ещё прикручивают математический сопроцессор, он нужен, чтобы постоянно вычислять эти ужасные плавающие запятые. Если попытаться уложить весь стандарт в два предложения, то получится примерно следующее: формат подразумевает три поля (знак, 8(11) разрядов поля порядка, 23(52) бита мантисса). Чтобы получить из этой битовой каши число надо $-1$ возвести в степень знака, умножить на 2 в степени порядка минус 127 и умножить на 1 + мантиссу делёную на два в степени размера мантиссы. Формула на экране, она не очень сложная. В остальном, ничего не понятно, но очень интересно, понимаю, давайте попробуем на примере. } +\begin{frame} + \frametitle{Типы, преобразование типов} + возьмём число +0,5 +\end{frame} +\note{ + с ним всё довольно просто, чтобы получить $+0,5$ нужно 2 возвести в $-1$ степень. поэтому, если развернуть обратно формулу, описанную выше, в знак и мантиссу мы ничего не пишем, оставляем 0, а в порядке должно быть 126, тогда мы должны будем $-1$ возвести в 0ю степень и получить положительный знак, умножить на 2 в степени $126-127 = -1$, получив внезапно 0,5 и умножить на 1 плюс пустая мантисса, в которой по сути не очень важно, что делить, что умножать и в какие степени возводить, всё равно 0 будет. Отсюда становится очевидно, что чем сложнее мантисса и чем меньше порядок, тем более точные и интересные числа мы можем получить. +} + +\begin{frame} + \frametitle{Типы, преобразование типов} + а что если -0,15625 +\end{frame} +\note{ + Попробуем немного сложнее: число $-0,15625$, чтобы понять как его записывать, откинем знак, это будет единица в разряде, отвечающем за знак, и посчитаем мантиссу с порядком. представим число как положительное и будем от него последовательно отнимать числа, являющиеся отрицательными степенями двойки, чтобы получить максимально близкое к нулю значение. +} + +\begin{frame} + \frametitle{Типы, преобразование типов} +$2^{1} = 2$ + +$2^{0} = 1.0$ + +$2^{-1} = 0.5$ + +$2^{-2} = 0.25$ + +$2^{-3} = 0.125$ + +$2^{-4} = 0.0625$ + +$2^{-5} = 0.03125$ + +$2^{-6} = 0.015625$ + +$2^{-7} = 0.0078125$ + +$2^{-8} = 0.00390625$ +\end{frame} +\note{ +получается, что $-1$ и $-2$ степени отнять не получится, мы явно уходим за границу нуля, а вот $-3$ прекрасно отнимается, значит порядок будет $127-3 = 124$, осталось понять, что получается в мантиссе. видим, что оставшееся после первого вычитания число - это 2 в $-5$ степени. значит в мантиссе мы пишем 01 и остальные нули. Получится, что +} + +\begin{frame} + \frametitle{Типы, преобразование типов} +$(-1)^1 \times 2^{(124-127)} \times (1 + \frac{2097152}{2^{23}}) = 1,15652$ + +\vspace{1em} + +$(-1)^1 \times 1,01e-3 = 1\times2^{-3} + 0\times2^{-4} + 1\times2^{-5} = 1\times0,125 + 0\times0,0625 + 1\times0,03125 = 0,125 + 0,03125 = 0,15625$. + +\end{frame} +\note{ +так наше число можно посчитать двумя способами: по приведённой на слайде формуле или последовательно складывая разряды мантиссы умноженные на двойку в степени порядка, уменьшая порядок на каждом шагу, как это показано на слайде. +} + +\begin{frame} + \frametitle{Типы, преобразование типов} + немного о хранении чисел с плавающей точкой + \includegraphics[width=100mm]{../pics/jc-02-float02.png} +\end{frame} +\note{ + Ну, что, поковырялись в детальках и винтиках, можно коротко поговорить об особенностях чисел с плавающей точкой, а именно: + \begin{itemize} + \item в числах с плавающей точкой бывает как положительный, так и отрицательный ноль, в отличие от целых чисел, где ноль всегда положительный + \item у чисел с плавающей запятой есть огромная зона, отмеченная на слайде, которая являет собой непредставимые числа слишком большие для хранения внутри такой переменной или настолько маленькие, что мнимая единица в мантиссе отсутствует + \item в таком числе можно хранить значение бесконечности + \item при работе с такими числами появляется понятие не-числа, при этом важно помнить, что NaN != NaN, а если очень сильно постараться, можно хранить там собственные данные, но это выходит далеко за пределы курса, и используется в каких-нибудь чрезвычайно маломощных процессорах для цифровой обработки сигналов, например. + \end{itemize} +} + +\begin{frame} + \frametitle{Типы, преобразование типов} + немного о хранении чисел с плавающей точкой + \includegraphics[width=120mm]{../pics/jc-02-float03.png} +\end{frame} +\note{ +у чисел с плавающей запятой могут иногда встречаться и проблемы в вычислениях, пример на слайде чрезвычайно грубый, но при работе, например, со статысячными или миллионными долями с такой проблемой вполне можно столкнуться. порядок выполнения действий может влиять на результат выполнения этих действий, что противоречит математике. +} + +% \begin{frame} +% \frametitle{Типы, преобразование типов} +% немного о хранении чисел с плавающей точкой +% Арифметические проблемы +% \begin{itemize} +% \item Не все числа имеют представление. +% \item Преобразование в целые: $63,0/9,0 \to 7$, $0,63/0,09 \to 6$. +% \item Многие числа нельзя ввести или вывести точно: $0,2 \to 0,200000000003$. +% \item Порядок вычисления может влиять на результат и его точность: не выполняются законы ассоциативности и дистрибутивности. +% \item Проблемы сравнения: $x == y$. +% \end{itemize} +% \end{frame} +% \note{ + +% } + \begin{frame} \frametitle{Типы, преобразование типов} таблица из методички «Основные типы данных в языке Java» \end{frame} \note{ - Что ещё важного мы видив в этой таблице? шесть из восьми примитивных типов могут иметь как положительные, так и отрицательные значения + Казалось бы, это было так давно, но вернёмся к нашей таблице с примитивными типами данных. Что ещё важного мы видив в этой таблице? шесть из восьми примитивных типов могут иметь как положительные, так и отрицательные значения они называются одним словом «знаковые» типы. } \begin{frame}