Главная страница

Подготовка к ревью на junior java dev. Книга Уорбэртон Функциональное программирование в массы java8


Скачать 483.96 Kb.
НазваниеКнига Уорбэртон Функциональное программирование в массы java8
АнкорПодготовка к ревью на junior java dev
Дата19.04.2022
Размер483.96 Kb.
Формат файлаdocx
Имя файлаreview (q1212).docx
ТипКнига
#484853
страница4 из 7
1   2   3   4   5   6   7

В каких пакетах лежат классы-потоки? -Классы потоков ввода\вывода лежат в java.io; С JDK 7 добавлен более современный способ работы с потоками - Java NIO. Классы лежат в java.nio. Для работы с архивами используются классы из пакета java.util.

  • Что вы знаете о классах-надстройках? - Классы-надстройки наделяют существующий поток дополнительными свойствами. Примеры классов: BufferedOutputStream, BufferedInputStream, BufferedWriter - буферизируют поток и повышают производительность.

  • Какой класс-надстройка позволяет читать данные из входного байтового потока в формате примитивных типов данных? - Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream.
    Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream.


    При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов.

    Класс DataInputStream позволяет читать элементарные данные из потока через интерфейс DataInput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.

    Конструктор: DataInputStream(InputStream stream)Методы: readDouble(), readBoolean(), readInt()

    1. Какой класс-надстройка позволяет ускорить чтение/запись за счет использования буфера? - Для этого используются классы, позволяющие буферизировать поток:

    BufferedInputStream(InputStream in)

    BufferedInputStream(InputStream in, int size)

    BufferedOutputStream(OutputStream out)

    BufferedOutputStream(OutputStream out, int size)

    BufferedReader(Reader r)

    BufferedReader(Reader in, int sz),java.io.BufferedWriter(Writer out)

    BufferedWriter(Writer out, int sz)

    1. Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?




    1. OutputStreamWriter - мост между классом OutputStream и классом Writer. Символы, записанные в поток, преобразовываются в байты.

    2) InputStreamReader - аналог для чтения. При помощи методов класса Reader читаются байты из потока InputStream и далее преобразуются в символы.



    1. Какой класс предназначен для работы с элементами файловой системы (ЭФС)? - В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов.

    Класс java.io.File может представлять имя определённого файла, а также имена группы файлов, находящихся в каталоге. Если класс представляет каталог, то его метод list() возвращает массив строк с именами всех файлов.

    Для создания объектов класса File можно использовать один из следующих конструкторов:

    File(File dir, String name) - указывается объект класса File (каталог) и имя файла

    File(String path) - указывается путь к файлу без указания имени файла

    File(String dirPath, String name) - указывается путь к файлу и имя файла

    File(URI uri) - указывается объекта URI, описывающий файл

    12) Какой символ является разделителем при указании пути к ЭФС? - Для различных систем символ разделителя различается. Вытащить его можно используя file.separator, а так же в статическом поле File.separator. Для Windows это '\'.*На stackoverflow встречал утверждение со ссылкой на документацию, что можно безопасно использовать слэш '/' для всех систем. В комментарии читатель подтвердил это.

    1. Что вы знаете об интерфейсе FilenameFilter? - Интерфейс FilenameFilter применяется для проверки попадает ли объект File под некоторое условие. Этот интерфейс содержит единственный метод boolean accept(File pathName). Этот метод необходимо переопределить и реализовать.

    2. Что такое сериализация? - Сериализация это процесс сохранения состояния объекта в последовательность байт; десериализация это процесс восстановления объекта, из этих байт. Java Serialization API предоставляет стандартный механизм для создания сериализуемых объектов.
      Сериализация в Java:
      http://habrahabr.ru/post/60317/

    Изучите секреты Java Serialization API: http://www.ccfit.nsu.ru/
  • deviv/courses/oop/java_ser_rus.html
    Как работает сериализация в Java (info.javarush.ru): http://goo.gl/K8GzJl


    1. Какие условия "благополучной" сериализации объекта? - Чтобы обладать способностью к сериализации, класс должен реализовывать интерфейс-метку Serializable. Так же все атрибуты и подтипы сериализуемого класса должны быть сериализуемы. Если класс предок был несереализуемым, то этот суперкласс должен содержать доступный (public, protected) конструктор без параметров для инициализации полей.

    2. Какие классы позволяют архивировать объекты? - DeflaterOutputStream, InflaterInputStream,

    ZipInputStream, ZipOutputStream, GZIPInputStream, GZIPOutputStream.

    Пример из http://www.concretepage.com/java/how_to_zip_file_java

    1. Основные отличия между Java IO и Java NIO –

    IO
    1) Блокирующий ввод-вывод


    Потоки ввода/вывода (streams) в Java IO являются блокирующими. Это значит, что когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого.

    2) Потокоориентированный ввод-вывод.

    Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. Если вы хотите произвести подобные манипуляции, вам придется сначала кэшировать данные в буфере.
    NIO

    1) Неблокирующий ввод-вывод

    Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания, поток выполнения может заняться чем-то другим.

    2) Буфероориентированный ввод-вывод. Селекторы Селекторы в Java NIO позволяют одному потоку выполнения мониторить несколько каналов ввода. Вы можете зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи.

    1. В чем отличие Scanner от BufferedReader? - Scanner позволяет разобрать строку на составляющие (токены), с помощью различных разделителей. Он не синхронизирован и, также не выбрасывает исключения.
      BufferedReader предназначен для чтения потока символов с буферизацией.


    2. Что делать, если одно из полей сериализовывать не нужно. - Это поле нужно пометить ключевым

    словом transient. И оно не будет сериализовано.

    1. Как сериализовать объект класса? - Нужно пометить его маркерным классом Serializable

    2. Какие форматы сериализации существуют?-

    1. JSON

    2. XML

    3. BinarySON - тот же JSON только в двоичном представлении.

    4. YAML - Yet Another Markup Language

    1. Cтандартные потоки ввода/вывода? - В языке Java стандартный поток ввода представлен переменной System.in. Эта переменная (объект) имеет тип InputStream. Класс InputStream есть абстрактный и размещается в вершине иерархии классов ввода.

    Стандартный поток вывода ассоциируется с переменной (объектом) System.out, тип которой PrintStream. Класс PrintStream содержит методы вывода на консоль print() и println().

    1. Классы байтовых потоков ввода и что они делают? –

    Классы, которые реализуют байтовые потоки ввода унаследованы от абстрактного класса InputStream:
    InputStream - абстрактный класс, который описывает поток ввода. Данный класс есть базовым для всех других классов системы ввода;


    BufferedInputStream - класс, который описывает буферизованные поток ввода;

    ByteArrayInputStream - класс, который описывает поток ввода, читающий байты из массива;

    DataInputStream -класс, который реализует методы для чтения данных стандартных типов, определенных в Java (int, double, float и т.д.);

    FileInputStream - класс, который реализует поток ввода, который читает данные из файла;
    FilterInputStream - это реализация абстрактного класса InputStream;


    ObjectInputStream - класс, реализующий поток ввода объектов;

    PipedInputStream - класс, соответствующий каналу ввода;

    PushbackInputStream - класс, соответствующий потоку ввода, который поддерживает возврат одного байта обратно в поток ввода;

    SequenceInputStream - класс, который реализует поток ввода, состоящий из двух или более потоков ввода, данные из которых читаются поочередно.

    1. Классы байтовых потоков вывода и что они делают?-

    Классы, которые реализуют байтовые потоки вывода унаследованы от абстрактного класса OutputStream:
    OutputStream - абстрактный класс, который описывает поток вывода. Все другие классы системы вывода есть подклассами класса OutputStream;


    BufferedOutputStream - класс, который имплементирует буферизованный поток вывода;
    ByteArrayOutputStream - класс, который реализует поток вывода, записывающий байты в массив;
    DataOutputStream - класс, который реализует поток вывода, содержащий методы для чтения данных стандартных типов, определенных в Java (int, float, double и т.п.);


    FileOutputStream - класс, который соответствует потоку вывода записывающему данные в файл;
    FilterOutputStream - класс, реализующий абстрактный класс OutputStream;


    ObjectOutputStream - класс, соответствующий потоку вывода объектов;

    PipedOutputStream - класс, который ассоциируется с каналом вывода;

    PrintStream - класс, который представляет собой поток вывода, содержащий методы print() и println().

    1. Классы символьных потоков ввода и что они делают?

    Reader - абстрактный класс, описывающий поток ввода символов. Этот класс есть суперклассом для всех нижеследующих подклассов;

    BufferedReader - класс, который описывает буферизованный поток ввода символов;

    CharArrayReader - класс, который реализует поток ввода, читающий символы из массива;

    FileReader - класс, который описывает поток ввода связанный с символьным файлом;
    FilterReader - класс, представляющий фильтрованный поток чтения;


    InputStreamReader - класс, который представляет собой поток ввода, превращающий байты в символы;

    LineNumberReader - класс, соответствующий потоку ввода, который подсчитывает строки;

    PipedReader - класс, который ассоциируется с каналом ввода;

    PushbackReader - класс, соответствующий потоку ввода, который позволяет возвращать символы обратно

    в поток ввода;

    StringReader - класс, который реализует поток ввода, читающий символы из строки.

    1. Классы символьных потоков вывода и что они делают?

    Writer - абстрактный класс, описывающий поток вывода символов. Все нижеследующие классы являются подклассами класса Writer;

    BufferedWriter - класс, который описывает буферизованный поток вывода символов;
    CharArrayWriter - класс, который соответствует потоку вывода, записывающему символы в массив;
    FileWriter - класс, который соответствует потоку вывода, записывающему символы в файл;
    FilterWriter - класс, реализующий фильтрованный поток записи;


    OutputStreamWriter - класс, реализующий средства преобразования символов в байты;

    PipedWriter - класс, который ассоциируется с каналом вывода;

    StringWriter - класс, который реализует поток вывода, записывающий символы в строку.

    1. На каком паттерне основана иерархия потоков ввода/вывода?

    Объекты классов Java, которые используются для ввода/вывода, для обеспечения необходимой функциональности наслаиваются друг на друга. Такая модель взаимодействия объектов поддерживается в паттерне «Декоратор». В этом паттерне при создании потока нужно использовать несколько объектов.

    1. Как работает метод read()?

    Метод read() - возвращает значение целого типа очередного байта, доступного во входном потоке; Метод read(byte arr) - метод для массового считывания данных, который считывает максимум байтов (не более arr.length) из потока, входящих данных в аргумент массива arr и возвращает фактическое количество байтов, считанных из потока;

    1. Как сериализовать объект класса. –

    Класс должен имплементировать маркерный интерфейс Serializable. Создаем ObjectOutputStream и передаем ему OutputStream/

    1. Как сериализовать статическое поле?

    При стандартной сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет. При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками.

    1. Можно ли сериализовать final поле?

    Поля с модификатором final сериализуются как и обычные. За одним исключением - их невозможно десериализовать при использовании Externalizable, поскольку final-поля должны быть инициализированы в конструкторе, а после этого в readExternal изменить значение этого поля будет невозможно. Соответственно, если необходимо сериализовать объект с final-полем неоходимо использовать только стандартную сериализацию.

    1. Клонирование Java –

    Java поддерживает два типа клонирования — поверхностное клонирование и глубокое клонирование.
    1) В случае поверхностного клонирования создается новый объект, который имеет точную копию значений в исходном объекте. Метод clone () объекта обеспечивает поверхностное клонирование. В этом механизме клонирования объект копируется без содержащихся в нем объектов.
    Клон копирует только структуру верхнего уровня объекта, а не нижние уровни.
    2) Существует так же второй вид клонирования объекта, который называется глубокое клонирование. Его используют в тех случаях, когда в клонируемом классе есть изменяемые объекты.


    1. Что такое «каналы»? –

    Каналы (channels) - это логические (не физические) порталы, абстракции объектов более низкого уровня файловой системы (например, отображенные в памяти файлы и блокировки файлов), через которые осуществляется ввод/вывод данных, а буферы являются источниками или приёмниками этих переданных данных. При организации вывода, данные, которые необходимо отправить, помещаются в буфер, который затем передается в канал. При вводе, данные из канала помещаются в заранее предоставленный буфер.
    Каналы напоминают трубопроводы, по которым эффективно транспортируются данные между буферами байтов и сущностями по ту сторону каналов. Каналы - это шлюзы, которые позволяют получить доступ к сервисам ввода/вывода операционной системы с минимальными накладными расходами, а буферы - внутренние конечные точки этих шлюзов, используемые для передачи и приема данных.


    Потоки (streams) применительно к вводу/выводу и работе с файлами. –

    Абстракция, которая используется для чтения или записи информации (файлов, сокетов, текста консоли и т.д.).

    1. Что делает метод read? Почему он возвращает int а не byte? Почему он не может возвращать byte? –

    Метод читает следующий байт из входящего потока. Когда метод ничего не может считать (конец потока), возвращается -1.

    Потому что нужно нужен такой тип, который может вместить 1 байт, плюс одно служебное значение -1 (обозначающее конец потока). Диапазон byte в Java лежит от -128 до 127, а возвращаемое значение метода read() лежит в диапазоне от 0 до 255.

    1. Что вернет метод read(), если он считывает файл и ему встречается байт равный -1? - 255

    2. Что такое клонирование? Как реализовано клонирование в Java? –

    В первую очередь необходимо реализовать интерфейс Cloneable. Если этого не сделать, при вызове метода clone() выбросится исключение CloneNotSupportedException. Интерфейс Cloneable является маркерным, то есть не имеет ни одного метода. Он показывает что объекты класса могут быть клонированы. Метод clone() является protected, поэтому класс может клонировать только собственные объекты. Для того, чтобы клонировать другие объекты, метод clone() нужно расширить до public.
    Пример клонирования:


    public User clone() {

    return (User) super.clone();}

    1. Поверхностное и глубокое клонирование. –

    Поверхностное клонирование применяется только с примитивными полями.

    Глубокое с примитивными и ссылочными.

    1. Чем отличается копирование от клонирования. Можно ли клонировать String, массив String.

    https://www.youtube.com/watch?v=TER05K_JGG8

    https://www.youtube.com/watch?v=mH1EJuyHvrQ

    1. Как преобразовать считанные байты в символы? Какой класс для этого используется? – InputStreamReader;

    Массив.можно преобразовать обратно в строку с помощью конструктора «new String(byte[])

    Метод «getBytes(charsetName)» класса String – преобразование char в byte

    1. В чём отличие File от Path?

    Path, по большому счету, — это переработанный аналог класса File. Работать с ним значительно проще, чем с File.

    Во-первых, из него убрали многие утилитные (статические) методы, и перенесли их в класс Files.

    Во-вторых, в Path были упорядочены возвращаемые значения методов.

    В классе File методы возвращали то String, то boolean, то File — разобраться было непросто.

    Полезные методы Path

    getFileName() — возвращает имя файла из пути;

    getParent() — возвращает «родительскую» директорию по отношению к текущему пути (то есть ту директорию, которая находится выше по дереву каталогов);

    getRoot() — возвращает «корневую» директорию; то есть ту, которая находится на вершине дерева каталогов;

    1. Почему важно закрывать потоки? Какие потоки можно не закрывать (не вызывать метод close())? - При закрытии потока освобождаются все выделенные для него ресурсы, например, файл. В случае, если поток окажется не закрыт, может происходить утечка памяти. Можно не закрывать промежуточные потоки, а закрыть только главные. Потоки имеют метод BaseStream. close() и реализуют AutoCloseable , но почти все экземпляры потока на самом деле не нужно закрывать после использования. Как правило, только потоки, источником которых является канал ввода-вывода

    2. Что делает метод available()? - int available() - возвращает количество байтов ввода,

    доступные в данный момент для чтения

    1. Можно ли использовать flush() для небуферизированного потока и что будет. Гарантируется ли запись данных в файл при вызове flush()? -  вызов метода flush() гарантирует только то, что байты, ранее записанные в поток, передаются операционной системе для записи, но не гарантирует записи на диск. По идее ничего случиться не должно.

    2. На каком паттерне основана иерархия потоков ввода/вывода? – на паттерне Декоратор (англ. Decorator) — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту

    3. Что возвращает перегруженный read. Какаое максимальное значение вернет? - int read() возвращает целочисленное представление следующего байта в потоке. Когда в потоке не останется доступных для чтения байтов, данный метод возвратит число -1. Максимальное значение 255

    Cтандартный метод read() – вернет значение следующего байта или -1 если его нет

    Перегруженный public int read(byte[] b) - количество прочитанных байтов или -1, если их нет

    Перегруженный public int read(byte[] b, int off, int len) – количество байтов, прочитанных в буффер

    1. Для чего нужен Scanner? Что такое токен в Scanner? Отличие Scanner’a от BufferedReader’a? Есть ли у сканера буфер?

    Класс Scanner используется для получения (считывания) данных введенных пользователем в виде Stringbyteshortintlongfloatdouble.

    Сканер выполняет поиск токенов во входной строке.

    Токен (или маркер) представляет собой серию цифровых или буквенно-цифровых символов, которая заканчивается разделителем.

    Разделителем может быть символ табуляции, возврат каретки (перевод строки или же просто ‘Enter’), конец файла или пробел. Сканер неявно создает буфер, т.к. основан на интерфейсе Readable - и единственный метод в этом интерфейсе основан на буфере.

    Scanner работает медленно, но зато предоставляет очень широкий API с кучей удобных методов, а BufferedReader работает быстрее, потому что читает часть входных данных в буфер, откуда они быстрее читаются по частям, то есть обращение к консоли происходит реже. 

    1. Методы класса File? Как создать файл на компьютере с помощью java? Как удалить директорию с файлами. Что если в ней есть вложенные директории ? В чём отличие File от Path?https://metanit.com/java/tutorial/6.11.php

    Для удаления файлов или папок в Java используется метод j ava. io. File delete() . Он возвращает true , если файл удалился успешно и возвращает false , если указанный для удаления файл не существует или не может быть удален.

    Если вы пытаетесь удалить папку, то этот метод проверяет указанную папку на пустоту. Если папка пуста, то она удаляется, если в папке что-то есть, то метод delete() просто возвращает false, то есть папка не удаляется.

    1. Какие поля не сериализуются?

    При стандартной сериализации поля, имеющие модификатор static, private поля или поля, помеченные модификатором transient не сериализуются. Соответственно, после десериализации

    это поле значения не меняет.

    1. Что будет при сериализации объекта у которого есть поле и оно не Serializable?

    1. В таком случае код скомпилируется.

    2. Но в рантайме при попытке сериализации, когда мы дойдем до этого поля и объекта, мы получим NotSerializableException.




    1. Externalizable vs Serializable? - При записи Serializable класса весь контроль над сериализацией достается JVM. С помощью определения специальных методов можно кастомизировать его части. Метод readObject при этом обычно начинается с вызова стандартной части сериализации – ObjectInputStream.defaultReadObject().

    Интерфейс Externalizable расширяет Serializable и добавляет методы записи и чтения writeExternal и readExternal. Входной и выходной потоки-аргументы в них представлены более абстрактно чем в специальных методах – интерфейсами ObjectInput и ObjectOutput.
    Этот интерфейс позволяет реализовать полностью свой механизм сериализации, стандартно запишется только идентификатор класса. Никакой автоматической работы с классом-родителем также не предусмотрено. Методы readObject и writeObject игнорируются. Ключевое слово transient эффекта на Externalizable не имеет.

    Externalizable объект в отличие от Serializable десерализуется не в обход конструктора, так что должен иметь конструктор без аргументов.

    1. Какие интерфейсы реализует InputStream/ OutputStream/ Reader/ Writer? - Closeable, AutoCloseable

    2. Пример адаптера и декоратора из IO?

    https://www.youtube.com/watch?v=iR0mHInZWM8&ab_channel=%D0%A3%D1%80%D0%BE%D0%BA%D0%B8Java

    https://www.youtube.com/watch?v=6xDBbYe11HQ&ab_channel=ExtremeCode

    https://www.youtube.com/watch?v=PIQTi9pc6Eo&ab_channel=SourceCode

    https://www.youtube.com/watch?v=IWcVI1LVBZg&ab_channel=DmitryAfanasyev

    1. Что такое потоки ввода-вывода? Как это реализовано в Java?

    Объект, из которого можно считать данные, называется потоком ввода, а объект, в который можно записывать данные, - потоком вывода. Например, если надо считать содержание файла, то применяется поток ввода, а если надо записать в файл - то поток вывода. В основе всех классов, управляющих потоками байтов, находятся два абстрактных класса: InputStream (представляющий потоки ввода) и OutputStream (представляющий потоки вывода)

    Но поскольку работать с байтами не очень удобно, то для работы с потоками символов были добавлены абстрактные классы Reader (для чтения потоков символов) и Writer (для записи потоков символов).

    1. Что делает метод read ()? Почему он возвращает int а не byte? Почему он не может возвращать byte?

    Потому что для работы метода read() нужен 1 байт (1 байт вмещает 255 чисел) + 1 символ. Поэтому byte не подойдёт, надо не 255 как в байт, а 256.

    1. Расскажи про класс File? Как создать новый файл на жестком диске?

    В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов.

    File file = new File(«file.txt»);

    File.createFile(); (метод создаёт новый файл).

    1. Как удалить файл при помощи класса File

    File file = new File(«file.txt»);

    File.delete(); (метод удаляет файл).


    1. Как удалить директорию при помощи delete() file

    public static void deleteFile(File element) {

    if (element.isDirectory()) {

    for (File sub : element.listFiles()) {

    deleteFile(sub);

    }

    }

    element.delete();
    Нужно обойти все внутренние директории и файлы, удалить их и потом только удалить саму директорию


    1. Различия между file path.

    Файл возвращает Boolean значения или string из методов, а path возвращает path..

    В классе file нет метода copy.

    Path бросает исключения и это удобно, file не бросает никаких исключений

    Утилитные методы убрали из path в новый класс files.
    1   2   3   4   5   6   7


    написать администратору сайта