Ответы на вопросы на собеседование Java core (часть 3).

  • Опишите иерархию исключений.

Все классы-исключения расширяют класс Throwable - непосредственное расширение класса object. 
У класса Throwable и у всех его расширений по традиции два конструктора:  
  • Throwable о - конструктор по умолчанию; 
  • Throwable (String message) - создаваемый объект будет содержать произвольное сообщение message. 
Записанное в конструкторе сообщение можно получить затем методом getMessage (). Если объект создавался конструктором по умолчанию, то данный метод возвратит null. 
Метод toString возвращает краткое описание события, именно он работал в предыдущих листингах. 
Три метода выводят сообщения обо всех методах, встретившихся по пути "полета" исключения: 
  • printstackTrace() - выводит сообщения в стандартный вывод, как правило, это консоль; 
  • printStackTrace(PrintStream stream) - выводит сообщения в байтовый поток stream; 
  • printStackTrace(PrintWriter stream) - выводит сообщения в символьный поток stream. 
У класса Throwable два непосредственных наследника - классы Error и Exception. Они не добавляют новых методов, а служат для разделения классов-исключений на два больших семейства - семейство классов-ошибок (error) и семейство собственно классов-исключений (exception). 
Классы-ошибки, расширяющие класс Error, свидетельствуют о возникновении сложных ситуаций в виртуальной машине Java. Их обработка требует глубокого понимания всех тонкостей работы JVM. Ее не рекомендуется выполнять в обычной программе. Не советуют даже выбрасывать ошибки оператором throw. He следует делать свои классы-исключения расширениями класса Error или какого-то его подкласса. 
 Имена классов-ошибок, по соглашению, заканчиваются словом Error. 
Классы-исключения, расширяющие класс Exception, отмечают возникновение обычной нештатной ситуации, которую можно и даже нужно обработать. Такие исключения следует выбросить оператором throw. Классов-исключений очень много, более двухсот. Они разбросаны буквально по всем пакетам J2SDK. В большинстве случаев вы способны подобрать готовый класс-исключение для обработки исключительных ситуаций в своей программе. При желании можно создать и свой класс-исключение, расширив класс Exception или любой его подкласс. 
 Среди классов-исключений выделяется класс RuntimeException - прямое расширение класса Exception. В нем и его подклассах отмечаются исключения, возникшие при работе JVM, но не столь серьезные, как ошибки. Их можно обрабатывать и выбрасывать, расширять своими классами, но лучше доверить это JVM, поскольку чаще всего это просто ошибка в программе, которую надо исправить. Особенность исключений данного класса в том, что их не надо отмечать в заголовке метода пометкой throws. 
 Имена классов-исключений, по соглашению, заканчиваются словом Exception.

  • Какие виды исключений в Java вы знаете, чем они отличаются? 

Все исключительные ситуации можно разделить на две категории: проверяемые(checked) и непроверяемые(unchecked).
Все исключения, порождаемые от Throwable, можно разбить на три группы. Они определяются тремя базовыми типами: наследниками Throwable - классами Errorи Exception, а также наследником Exception - RuntimeException.
Ошибки, порожденные от Exception (и не являющиеся наследниками RuntimeException ), являются проверяемыми. Т.е. во время компиляции проверяется, предусмотрена ли обработка возможных исключительных ситуаций. Как правило, это ошибки, связанные с окружением программы (сетевым, файловым вводом-выводом и др.), которые могут возникнуть вне зависимости от того, корректно написан код или нет. Например, открытие сетевого соединения или файла может привести к возникновению ошибки и компилятор требует от программиста предусмотреть некие действия для обработки возможных проблем. Таким образом повышается надежность программы, ее устойчивость при возможных сбоях.
Исключения, порожденные от RuntimeException, являются непроверяемыми и компилятор не требует обязательной их обработки.
Как правило, это ошибки программы, которые при правильном кодировании возникать не должны (например, IndexOutOfBoundsException- выход за границы массива, java.lang.ArithmeticException- деление на ноль). Поэтому, чтобы не загромождать программу, компилятор оставляет на усмотрение программиста обработку таких исключений с помощью блоков try-catch.
Исключения, порожденные от Error, также не являются проверяемыми. Они предназначены для того, чтобы уведомить приложение о возникновении фатальной ситуации, которую программным способом устранить практически невозможно (хотя формально обработчик допускается). Они могут свидетельствовать об ошибках программы, но, как правило, это неустранимые проблемы на уровне JVM. В качестве примера можно привести StackOverflowError (переполнение стека), OutOfMemoryError (нехватка памяти).
Методы, код которых может порождать проверяемые исключения, должны либо сами их обрабатывать, либо в заголовке метода должно быть указано ключевое слово throws с перечислением необрабатываемых проверяемых исключений. На непроверяемые ошибки это правило не распространяется.
Переопределенный (overridden) метод не может расширять список возможных исключений исходного метода.

  • Что такое checked и unchecked Exception?

Checked исключения, это те, которые должны обрабатываться блоком catch или описываться в сигнатуре метода. Unchecked могут не обрабатываться и не быть описанными.
 Unchecked исключения в Java - наследованные от RuntimeException, Checked - от Exception.
 Пример unchecked исключения - NullPointerException, checked исключения - IOException.

  • Как создать свой unchecked Exception?

Унаследоваться от RuntimeException.

  • Какие есть Unchecke exeption?


  • Что такое Error?

Исключения, порожденные от Error, не являются проверяемыми. Они предназначены для того, чтобы уведомить приложение о возникновении фатальной ситуации, которую программным способом устранить практически невозможно (хотя формально обработчик допускается). Они могут свидетельствовать об ошибках программы, но, как правило, это неустранимые проблемы на уровне JVM. В качестве примера можно привести StackOverflowError (переполнение стека), OutOfMemoryError (нехватка памяти).
Методы, код которых может порождать проверяемые исключения, должны либо сами их обрабатывать, либо в заголовке метода должно быть указано ключевое слово throws с перечислением необрабатываемых проверяемых исключений. На непроверяемые ошибки это правило не распространяется.

  • Опишите работу блока try-catch-finally.

Если срабатывает один из блоков catch, то остальные блоки в данной конструкции try-catch выполняться не будут.
Cвойством транзакционности исключения не обладают - действия, произведенные в блоке try до возникновения исключения, не отменяются поcле его возникновения.

  • Возможно ли использование блока try-finally (без catch)?

try может быть в паре с finally, без catch. Работает это точно так же - после выхода из блока try выполняется блок finally. Это может быть полезно, например, в следующей ситуации. При выходе из метода вам надо произвести какое-либо действие. А return в этом методе стоит в нескольких местах. Писать одинаковый код перед каждым return нецелесообразно. Гораздо проще и эффективнее поместить основной код в try, а код, выполняемый при выходе - в finally.

  • Всегда ли исполняется блок finally?

Не всегда например в следующих ситуациях:
  1. Существуют потоки-демоны - потоки предоставляющие некие сервисы, работая в фоновом режиме во время выполнения программы, но при этом не являются ее неотъемлеммой частью.Таким образом когда все потоки не демоны завершаются, программа завершает свою работу. В потоках демонах блок finally не выполняеться, они прерываются внезапно.
  2. System.exit(0)
  3. если в блоке finally произошло исключение и нет обработчика, то оставшийся код в блоке finally может не выполнятся.

  • Какие есть оссобенности класса String? что делает метод intern().

  1. Внутреннее состояние класса String нельзя изменить после его создания, т.е. этот класс неизменяемый (immutable) поэтому когда вы пишете String str = "One" + "Two"; создается три! объекта класса String. 
  2. От него нельзя унаследоваться, потому что класс String объявлен как final: public final class String
  3. Метод hashCode класса String переписан и возвращает: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 
  4. У класса String есть метод public String intern(), который возвращает строку в каноническом ее представлении из внутреннего пула строк, поддерживаемого JVM, он нужен чтобы вместо String.equals() использовать ==.
Понятно, что оператор сравнения ссылок выполняется гораздо быстрее, чем посимвольное сравнение строк.
Используют в основном, где приходится сравнивать много строк, например в каких нибудь XML парсерах.
А вообще по увеличению производительности ещё вопрос. Ибо метод intern() тогда должен выполняться быстрее чем equals(), каждый раз когда вы вызываете метод intern() просматривается пул строк на наличие такой строки и если такая уже есть в пуле, то возвращается ссылка на нее.Сравниваются они через equal().

  • Можно ли наследовать строковый тип, почему?

Классы объявлены final, поэтому наследоваться не получится.

  • Почему строка является популярным ключом в HashMap в Java?

Поскольку строки неизменны, их хэшкод кэшируется в момент создания, и не требует повторного пересчета. Это делает строки отличным кандидатом для ключа в Map и они обрабатываются быстрее, чем другие объекты-ключи HashMap. Вот почему строки преимущественно используются в качестве ключей HashMap.

  • Дайте определение понятию конкатенация строк.

Конкатенация - операция объединения строк. Результатом является объединения второй строки с окончанием первой. Операция конкатенации могут быть выполнены так:

  • Как перевернуть строку?

Один из способов как это можно сделать:

  • Как сравнить значение двух строк?

Строка в Java - это отдельный объект, который может не совпадать с другим объектом, хотя на экране результат выводимой строки может выглядеть одинаково. Оператор == (а также !=) работает с ссылками объекта String. Если две переменные String указывают на один и тот же объект в памяти, сравнение вернет результат true. В противном случае результат будет false, несмотря на то что текст может содержать в точности такие же символы.
Для сравнения посимвольно на эквивалентность необходимо использовать метод equals().

  • Как обрезать пробелы в начале и конце строки?

Небольшой пример:

  • Дайте определение понятию "пул строк".

Пул строк - это набор строк, который хранится в памяти Java heap. Мы знаем, что String это специальный класс в Java, и мы можем создавать объекты этого класса, используя оператор new точно так же, как и создавать объекты, предоставляя значение строки в двойных кавычках.
Диаграмма ниже объясняет, как пул строк размещается в памяти Java heap и что происходит, когда мы используем различные способы создания строк.
Пул строк возможен исключительно благодаря неизменяемости строк в Java и реализации идеи интернирования строк.
Пул строк помогает экономить большой объем памяти, но с другой стороны создание строки занимает больше времени.
Когда мы используем двойные кавычки для создания строки, сначала ищется строка в пуле с таким же значением, если находится, то просто возвращается ссылка, иначе создается новая строка в пуле, а затем возвращается ссылка.
Тем не менее, когда мы используем оператор new, мы принуждаем класс String создать новый объект строки, а затем мы можем использовать метод intern() для того, чтобы поместить строку в пул, или получить из пула ссылку на другой объект String с таким же значением.

  • Можно ли синхронизировать доступ к строке?

String сам по себе потокобезопасный класс. Если мы мы работаем с изменяемыми строками, то нужно использовать StringBuffer.

  • Как правильно сравнить значения строк двух различных объектов типа String и StringBuffer?

Привести их к одному типу и сравнить.

  • Почему строка неизменная и финализированная в Java?

Есть несколько преимуществ в неизменности строк:
  • Строковый пул возможен только потому, что строка неизменна в Java, таким образом виртуальная машина сохраняет много места в памяти(heap space), поскольку разные строковые переменные указывают на одну переменную в пуле. Если бы строка не была неизмененяемой, тогда бы интернирование строк не было бы возможным, потому что если какая-либо переменная изменит значение, это отразится также и на остальных переменных, ссылающихся на эту строку.
  • Если строка будет изменяемой, тогда это станет серьезной угрозой безопасности приложения. Например, имя пользователя базы данных и пароль передаются строкой для получения соединения с базой данных и в программировании сокетов реквизиты хоста и порта передаются строкой. Так как строка неизменяемая, её значение не может быть изменено, в противном случае любой хакер может изменить значение ссылки и вызвать проблемы в безопасности приложения.
  • Строки используются в Java classloader и неизменность обеспечивает правильность загрузки класса при помощи Classloader. К примеру, задумайтесь об экземпляре класса, когда вы пытаетесь загрузить java.sql.Connection класс, но значение ссылки изменено на myhacked.Connection класс, который может осуществить нежелательные вещи с вашей базой данных.
  • Поскольку строка неизменная, её hashcode кэшируется в момент создания и нет необходимости рассчитывать его снова. Это делает строку отличным кандидатом для ключа в Map и его обработка будет быстрее, чем других ключей HashMap. Это причина, почему строка наиболее часто используемый объект, используемый в качестве ключа HashMap.

  • Напишите метод удаления данного символа из строки.

Мы можем использовать метод replaceAll для замены всех вхождений в строку другой строкой. Обратите внимание на то, что метод получает в качестве аргумента строку, поэтому мы используем класс Character для создания строки из символа, и используем её для замены всех символов на пустую строку.

Java core (часть 4).

Рассказать друзьям:

9 коментарі :

  1. Анонимный4 июня 2016 г., 17:58

    Почему это "One"+"Two" создаст три строки, когда это свернется в одну строку в констант пуле еще на этапе компиляции в байт-код?

    ОтветитьУдалить
    Ответы
    1. Ну и где там ответ на вопрос? "The compiler creates 1 String per JVM start..". То есть ни о каких 3 строках там ни слова.

      Удалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить
  3. По поводу пула стрингов.
    http://www.journaldev.com/797/what-is-java-string-pool

    ОтветитьУдалить
  4. Нажимая на кнопку СЛЕДУЮЩЕЕ пропускается CORE часть 4, попадаю на сл. тему - коллекции.

    ОтветитьУдалить
  5. почему вопрос про uncheсked - ы, а перечислены cheсked - ы?
    и в самом вопросе забыли последнюю букву, написано uncheke

    ОтветитьУдалить