1. Что такое InputStream и OutputStream
Скачать 18.64 Kb.
|
1. Что такое InputStream и OutputStream. InputStream - это Абстрактный класс, являющийся базовым классом для всех классов, представляющий поток ввода. OutputStream - это Абстрактный класс, представляющий выходной поток байт 2. Почему важно закрывать потоки. При закрытии потока освобождаются все выделенные для него ресурсы, например, файл. В случае, если поток окажется не закрыт, может происходить утечка памяти. 3. Какие потоки можно не закрывать (не вызывать метод close()). Если используется конструкция try-with-resourse У нее есть специальный интерфейс AutoCloseble. avail 4. Что делает метод available(). Метод возвращает количество байт, которое еще осталось в потоке 5. Можно ли использовать flush() для небуферизированного потока и что будет. Можно т.к исходя из документации, "среда хоста может выполнять свою собственную буферизацию, неизвестную Java. В этом случае запись можешь кэшироваться в буферах ОС". 6. На каком паттерне основана иерархия потоков ввода/вывода. Объекты классов Java, которые используются для ввода/вывода, для обеспечения необходимой функциональности наслаиваются друг на друга. Такая модель взаимодействия объектов поддерживается в паттерне «Декоратор». В этом паттерне при создании потока нужно использовать несколько объектов. 7. Что делает метод read. Почему он возвращает int а не byte. Почему он не может возвращать byte. Метод читает следующий байт из входящего потока. Когда метод ничего не может считать (конец потока), возвращается -1. Потому что нужно нужен такой тип, который может вместить 1 байт, плюс одно служебное значение -1 (обозначающее конец потока) Диапазон byte в Java лежит от -128 до 127, а возвращаемое значение метода read() лежит в диапазоне от 0 до 255. 8. Что вернет метод read(), если он считывает файл и ему встречается байт равный -1. 255. 9. Что возвращает перегруженный read. Какое максимальное значение вернет. Максимально, read может ввести 65534 байта, т.к. 65535 это -1, индикатор ошибки. int read() - возвращает представление очередного доступного символа во входном потоке в виде целого числа. int read(char[] buffer) - пытается прочесть максимум buffer.length символов из входного потока в массив buffer. Возвращает количество символов, в действительности прочитанных из потока. int read(char[] buffer, int offset, int length) - пытается прочесть максимум length символов, расположив их в массиве buffer, начиная с элемента offset. Возвращает количество реально прочитанных символов. 10. Гарантируется ли запись данных в файл при вызове flush(). Если предполагаемое место назначения этого потока является абстракцией, предоставляемой базовой операционной системой, например файлом, то очистка потока гарантирует только то, что байты, ранее записанные в поток, передаются операционной системе для записи; это не гарантирует, что они действительно записаны на физическое устройство, такое как дисковый накопитель. **Scanner 1. Для чего нужен Scanner. Класс Scanner используется для считывания введенных пользователем данных следующих типов: String, byte, short, int, long, float, double. 2. Что такое токен в Scanner. Токен - это подстрока, не содержащая разделителей и ограниченная слева и справа разделителями. Стандартными разделителями являются: пробел ' ', символ табуляции '\t', перевода строки '\n' и возврата каретки '\r'. 3. Отличие Scanner’a от BufferedReader’a. BufferedReader работает синхронно, а Scanner — нет. BufferedReader следует использовать, если мы работаем с несколькими потоками. BufferedReader имеет значительно большую буферную память, чем Scanner. Сканер имеет небольшой буфер (1KB буфер символов) в отличие от BufferedReader (8KB байтовый буфер), но этого более чем достаточно. BufferedReader немного быстрее по сравнению со сканером, потому что сканер выполняет синтаксический анализ входных данных, а BufferedReader просто читает последовательность символов. При использовании BufferReader нужно указывать IO Exception. 4. Есть ли у сканера буфер. У сканнера есть бафер, его размер 1KB (Буфер символов) **Файл 1. Абсолютны и относительный путь. Абсолютный (полный) путь — это путь, который указывает на одно и то же место в файловой системе, вне зависимости от текущей рабочей директории или других обстоятельств. Полный путь всегда начинается с корневого каталога. Относительный путь представляет собой путь по отношению к текущему рабочему каталогу пользователя или активного приложения. 2. Методы File boolean createNewFile() создает новый файл boolean delete() удаляет файл boolean exists() проверяет есть ли каталог или файл String getAbsolutePath() возвращает путь getName() имя getParent() имя род класса isDirectory() если есть каталог, тру isFile() если находится файл, тру isHidden() если файл скрытый, тру length() размер файла в байтах lastModified() время изменения list() возвращает массив файлов и катологов listFiles() возвращает массив файлов и подкатологов mkdir() создает каталог renameTo(File dest) переименовывает 3. Как создать файл на компьютере с помощью java. Создать файл в Java можно одним из трех способов, передав в объект File абсолютный путь, только указать имя файла, указать относительный путь (в этом случае объект файла пытается найти файлы в корневой директории проекта). + нужно вызвать метод createNewFile(). 4. Как удалить директорию с файлами. Что если в ней есть вложенные директории. Методом delete. Директория будет удалена только в случае если в ней нет файлов, либо вложенных директорий. 5. В чём отличие File от Path. Многие методы класса file не сообщают нам никаких подробностей о возникшей проблеме или даже вообще не выдают исключений, в отличии от методов Path. 2) Поддержка метаданных. Класс файла в java.io пакет имеет плохую поддержку метаданных, что приводит к проблемам на разных платформах с операциями ввода-вывода, требующими метаинформации о файлах. Метаданные могут также включать разрешения, владельца файла и атрибуты безопасности. Из-за этого класс File вообще не поддерживает символические ссылки, а метод rename() не работает согласованно на разных платформах. 3) Производительность. Вместо File в пакете NIO для работы с файлами появились такие классы, как Paths, Path, Files. Класс Paths содержит один статический метод get (ссылка на объект) для создания объекта Path. Files — это утилитный класс, куда были вынесены статические методы из класса File. **Клонирование 1. Что такое клонирование. Как реализовано клонирование в Java. В первую очередь необходимо реализовать интерфейс Cloneable. Если этого не сделать, при вызове метода clone() выбросится исключение CloneNotSupportedException. Интерфейс Cloneable является маркерным, то есть не имеет ни одного метода. Он показывает что объекты класса могут быть клонированы. Метод clone() является protected, поэтому класс может клонировать только собственные объекты. Для того, чтобы клонировать другие объекты, метод clone() нужно расширить до public. Пример клонирования: public User clone() { return (User) super.clone(); } 2. Клонирование объекта. Глубокое и поверхностное. Поверхностное клонирование применяется только с примитивными полями. Глубокое с примитивными и ссылочными. 1) В случае поверхностного клонирования создается новый объект, который имеет точную копию значений в исходном объекте. Метод clone () объекта обеспечивает поверхностное клонирование. В этом механизме клонирования объект копируется без содержащихся в нем объектов. Клон копирует только структуру верхнего уровня объекта, а не нижние уровни. 2) Существует так же второй вид клонирования объекта, который называется глубокое клонирование. Его используют в тех случаях, когда в клонируемом классе есть изменяемые объекты. Реализация глубокого клонирования Все классы-члены в оригинальном классе должны поддерживать клонирование. Для каждого члена класса должен вызываться super.clone() при переопределении метода clone(); Если какой-либо член класса не поддерживает клонирование, то в методе клонирования необходимо создать новый экземпляр этого класса и скопировать каждый его член со всеми атрибутами в новый объект класса, по одному. 3. Чем отличается копирование от клонирования. clone-создайте что-то новое на основе чего-то существующего. копирование-копирование с чего-то существующего на что-то другое 4. Можно ли клонировать String, массив String. Строку нет, массив можно 5. Какое клонирование в Java по умолчанию? Поверхностное **Сериализация 1. Что такое сериализация и десериализация. Сериализация это процесс сохранения состояния объекта в последовательность байт; десериализация это процесс восстановления объекта, из этих байт 2. Назовите несколько форматов сериализации. 1. JSON JavaScript Object Notation 2. XML 3. BinarySON - тот же JSON только в двоичном представлении. 4. YAML - Yet Another Markup Language 3. Как сериализовать объект класса. Нужно пометить его маркерным классом Serializable 1) Класс объекта должен реализовывать интерфейс Serializable 2) Создать поток ObjectOutputStream (oos), который записывает объект в переданный OutputStream. 3) Записать в поток: oos.writeObject(Object); 4) Сделать oos.flush() и oos.close() 4. Что делать, если одно из полей сериализовывать не нужно. Это поле нужно пометить ключевым словом transient. 5. Как сериализовать статическое поле. При стандартной сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет. При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками. 6. Externalizable vs Serializable Производительность. Интерфейс Serializable имеет много плюсов (простота, удобство), но производительность не из их числа. Гибкость. Serializable вообще не позволяет управлять процессом, кроме исключения полей или добавление (через свою реализацию методов writeObject/readObject). Безопасность. Иногда необходимо шифрование данных. 7. Что если я не хочу сериализовывать поле. Что если при десериализации поменять тип. выбросит исключение 8. Что будет если перед десериализцией изменится класс, почему будет выброшено исключение. Изменится поле private static final long serialVersionUID. А затем будет выброшено исключение java.io.InvalidClassException. Если же поле создать явно и присвоить значение, то дальше уже всё зависит от того какие изменения произошли в классе, совместимые или несовместимые для сериализации. 9. Что будет при сериализации объекта у которого есть поле и оно не Serializable. код скомпилируется в процессе выполнения вылетит исключение NotSerializableException. 10. Особенность сериализации поля final. Поля с модификатором final сериализуются как и обычные. За одним исключением - их невозможно десериализовать при использовании Externalizable, поскольку final-поля должны быть инициализированы в конструкторе, а после этого в readExternal изменить значение этого поля будет невозможно. Соответственно, если необходимо сериализовать объект с final-полем необходимо использовать только спотоктандартную сериализацию. 11. Какие поля не сериализуются. Помеченные ключевым словом transient, статические. 12. Выполнится ли flush если мы сделаем close у потока? да 13. Какие плюсы имеет Externalizable? 14. Что такое канонический путь? абсолютный 15. Какие объекты можно сириализовать? Сразу надо сказать, что сериализовать можно только те объекты, которые реализуют интерфейс Serializable. Этот интерфейс не определяет никаких методов, просто он служит указателем системе, что объект, реализующий его, может быть сериализован. Сериализация. Класс ObjectOutputStream. Общие вопросы 1. Отличие пакетов IO и NIO, InputStream от Reader. IO 1) Блокирующий ввод-вывод Потоки ввода/вывода (streams) в Java IO являются блокирующими. Это значит, что когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого. 2) Потокоориентированный ввод-вывод. Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. Если вы хотите произвести подобные манипуляции, вам придется сначала кэшировать данные в буфере. NIO 1) Неблокирующий ввод-вывод Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания, поток выполнения может заняться чем-то другим. 2) Буфероориентированный ввод-вывод. 3) Селекторы Селекторы в Java NIO позволяют одному потоку выполнения мониторить несколько каналов ввода. Вы можете зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи. 2. Что такое System.in, что такое System.out. Переменная System.out ссылается на стандартный поток вывода. По умолчанию это консоль Переменная System.in ссылается на стандартный поток ввода, которым по умолчанию является клавиатура 3. Какие интерфейсы реализует InputStream/ OutputStream/ Reader/ Writer. Если объект реализует интерфейс OutputStream, значит, он поддерживает последовательную запись в него байт (byte). Если объект реализует интерфейс Reader, значит, он поддерживает последовательное чтение из него символов (char). Если объект реализует интерфейс Writer, значит, он поддерживает последовательную запись в него символов (char). Поток вывода напоминает принтер. На принтер мы можем выводить документы. 4. Что такое паттерн адаптер. Адаптер — это структурный паттерн, который позволяет подружить несовместимые объекты. 5. Пример адаптера и декоратора из IO. 6. Thread и Runnable, что выбрать? Зачем нужно два вида реализации многопоточности? Реализация интерфейса Runnable используется в случаях, когда класс уже наследует какой-либо родительский класс и не позволяет расширить класс Thread. К тому же хорошим тоном программирования в java считается реализация интерфейсов. Это связано с тем, что в java может наследоваться только один родительский класс. Таким образом, унаследовав класс Thread, невозможно наследовать какой-либо другой класс. Расширение класса Thread целесообразно использовать в случае необходимости переопределения других методов класса помимо метода run(). |