В этом месяце я сдавал экзамен SCJP. В этом топике я расскажу о подготовке и экзамене.
В основном для тех, кто собирается сдавать и кому нужно больше информации об этом.
Так как Sun'a больше нет, то и экзамена SCJP тоже нет. Теперь он значится так:
1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam.
Подготовка заняла две недели. Использовал только эти источники:
Чтобы попробовать себя, есть еще такие ресурсы:
Всё. Этого хватит, чтобы сдать экзамен (и не с минимальным проходным баллом, а с очень даже хорошим). Правда, это при условии, что всё-таки вы на Джаве программировали и не путаетесь в основных конструкциях.
Я просто читал вышеупомянутые статьи. Иногда что-то проверял на практике. Тесты в эмуляторе прошел по разу. Смотрел то, что неправильно, чтобы в будущем не натыкаться на те же грабли.
Сдавал в Петербурге. Экзамен стоит 125$ (сама организация экзамена. Положительный результат не гарантирован :)).
В экзаменационном центре встретили радушно, напоили чаем, угостили печеньками. Сфотографировали. Потом начался тест. Сдавал в одиночестве (комната рассчитана на двоих сдающих, но я был один). 150 минут на 60 вопросов. Тут ничего особенного — тест как во всех эмуляторах.
Надо ответить правильно не менее, чем на 61% вопросов.
Пользоваться ничем нельзя, выходить — можно. Время при этом не останавливается.
Результат — сразу. Сертификат — через несколько недель по почте.
В стиле статей «Знаешь ли ты java» покажу несколько интересных и не самых обычных задач с экзамена. Опять же, в первую очередь для тех, кто хочет попрактиковаться перед экзаменом. Ведь самый верный способ подготовиться: решать, решать и решать.
Ответы приведены после каждого вопроса.
Что произойдет после выполнения этого кода?
1. Будет создан и каталог и файл
2. Только каталог
3. Не скомпилируется
4. Выбросится java.io.IOException
Ответ:
2. Только каталог (с именем somename). Больше ничего не произойдет.
Что будет выведено в результате выполнения этого кода?
1. Не скомпилируется
2. Выбросится java.io.NotSerializableException
3. 1 2 3
4. 1 2 3 A B
Ответ:
4. 1 2 3 A B
Наличие в классе C переменной A a = null не ведет к NotSerializableException, так как a = null. Если вместо public A a = null; написать public A a = new A(); — выкинется NotSerializableException.
В данном же случае все будет сериализовываться. При десериализации не вызывается конструктор дессириализуемого класса, но если его родители не реализуют интерфейс Serializable, то у них вызывается конструктор по умолчанию.
Если в этом примере A будет реализоываться Serializable, а не C, то вывод будет 1 2 3
Если в этом примере во всех трех классах убрать конструктор без параметров, то при десериализации выкинется java.io.InvalidClassException: no valid constructor, так как джава пытается вызвать конструктор без параметров у родителя.
Что будет выведено в результате выполнения этого кода?
1. 1 2 3
2. 3 2 1
3. 3 1 2
4. Не скомпилируется
5. Ошибка времени выполнения
Ответ:
3. 3 1 2.
То, что метод и лист внутри метода называются getSorted() и sorted, вовсе не означает, что LinkedList тоже sorted.
Что будет выведено в результате выполнения этого кода?
1. true true false
2. true false false
3. Ошибка компиляции
Ответ:
3. Ошибка компиляции. Так произойдет, потому что D и C находятся на разных ветках иерархии и не приводимы друг к другу.
1. list.add(«Привет, Хабрахабр!»);
2. list.add(new Object());
3. list = new ArrayList();
4. list = new ArrayList<?>();
5. list = new ArrayList<Objeсt>();
Ответ:
3. list = new ArrayList();
Всё логично: вдруг к нам придет List<Т>, где T и правда наследуется от String?.. Тогда при вызове list.add(«Привет, Хабрахабр!»); джава просто не сможет сделать преобразование типов. Понимая это, компилятор компилироваться коду со строкой '1' не даёт. С 2, 4, 5 — тоже всё понятно. list = new ArrayList(); — корректный код.
Что будет выведено в результате выполнения этого кода?
1. B
2. Ничего
3. Ошибка компиляции
4. Exception
Ответ:
Переопределяющий метод не должен бросать новое или более широкое по классу исключение. Не бросать его вообще он может. Так что код скомпилируется и выведет B.
Что будет выведено в результате выполнения этого кода?
1. B
2. Ничего
3. Ошибка компиляции
4. Exception
Ответ:
3. Ошибка компиляции.
Так как мы в классе A объявлено исключение, а в main(...) мы его не обрабатываем. Тип возвращаемого значения (который может быть не таким, как в суперклассе, ведь есть covariant return) и выбрасываемые исключения проверяются компилятором по типу ссылки.
Как можно изменить класс A, чтобы не повлиять на клиентский класс?
1. Заменить ++i на i++
2. Заменить public void add(int i) на private void add(int i)
3. Заменить public void add(int i) на public void add(Integer i)
4. Ничего из вышеперечисленного
Ответ:
3. Заменить public void add(int i) на public void add(Integer i)
Просто нужно знать, что ++ и -- работает и с Integer. И с Double. И с Float. И со всеми численными обертками.
Читайте статьи, практикуйтесь. И всё получится. Сложного в этом ничего нет.
Если есть какие-то вопросы об экзамене, отвечу в комментариях.
В основном для тех, кто собирается сдавать и кому нужно больше информации об этом.
Уточнение
Так как Sun'a больше нет, то и экзамена SCJP тоже нет. Теперь он значится так:
1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam.
Подготовка
Подготовка заняла две недели. Использовал только эти источники:
- Знаешь ли ты JAVA, %username%?
Знаешь ли ты JAVA, %username%? Часть вторая
За эти две статьи автору огромное спасибо. - На хабре, в комментариях, нашел еще ссылку вот на эту статью: http://rsdn.ru/article/java/scjp_article.xml
Осмыслив ее, и зная всё, что там написано, можете считать, что экзамен почти сдан. - Еще есть на хабре статья Java сертификация — прохождение SCJP и SCBCD.
Чтобы попробовать себя, есть еще такие ресурсы:
- nikojava.wordpress.com
Эти записи блога — сборник экзаменационных задач с ответами (правда, были и ошибочные ответы, будьте внимательны! При сомнениях — дайте на проверку компилятору). - http://www.certpal.com/
Это эмулятор экзамена. Примерно так экзамен и выглядит.
Всё. Этого хватит, чтобы сдать экзамен (и не с минимальным проходным баллом, а с очень даже хорошим). Правда, это при условии, что всё-таки вы на Джаве программировали и не путаетесь в основных конструкциях.
Я просто читал вышеупомянутые статьи. Иногда что-то проверял на практике. Тесты в эмуляторе прошел по разу. Смотрел то, что неправильно, чтобы в будущем не натыкаться на те же грабли.
Экзамен
Сдавал в Петербурге. Экзамен стоит 125$ (сама организация экзамена. Положительный результат не гарантирован :)).
В экзаменационном центре встретили радушно, напоили чаем, угостили печеньками. Сфотографировали. Потом начался тест. Сдавал в одиночестве (комната рассчитана на двоих сдающих, но я был один). 150 минут на 60 вопросов. Тут ничего особенного — тест как во всех эмуляторах.
Надо ответить правильно не менее, чем на 61% вопросов.
Пользоваться ничем нельзя, выходить — можно. Время при этом не останавливается.
Результат — сразу. Сертификат — через несколько недель по почте.
Задачи
В стиле статей «Знаешь ли ты java» покажу несколько интересных и не самых обычных задач с экзамена. Опять же, в первую очередь для тех, кто хочет попрактиковаться перед экзаменом. Ведь самый верный способ подготовиться: решать, решать и решать.
Ответы приведены после каждого вопроса.
1. I/O — знай сигнатуры методов
Что произойдет после выполнения этого кода?
public class Main{
public static final void main(String[] args) {
String path = "somepath"; // путь существующий и все права на запись есть
String name = "somename";
File file = new File(path, name);
file.mkdir();
try {
file.createNewFile();
} catch (Exception e) {
}
}
}
1. Будет создан и каталог и файл
2. Только каталог
3. Не скомпилируется
4. Выбросится java.io.IOException
Ответ:
2. Только каталог (с именем somename). Больше ничего не произойдет.
2. Сериализация и конструкторы
Что будет выведено в результате выполнения этого кода?
import java.io.*;
import java.util.*;
public class Main {
public static final void main(String[] args) throws Exception {
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("abra-cadabra"));
out.writeObject(new C(123));
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("abra-cadabra"));
System.out.print(in.readObject());
}
}
class A {
public A() {
System.out.print("A ");
}
public A(int number) {
System.out.print("1 ");
}
}
class B extends A {
public B() {
System.out.println("B ");
}
public B(int number) {
super(number);
System.out.print("2 ");
}
}
class C extends B implements Serializable {
public C() {
System.out.print("C ");
}
public A a = null;
public C(int number) {
super(number);
System.out.print("3 ");
}
}
1. Не скомпилируется
2. Выбросится java.io.NotSerializableException
3. 1 2 3
4. 1 2 3 A B
Ответ:
4. 1 2 3 A B
Наличие в классе C переменной A a = null не ведет к NotSerializableException, так как a = null. Если вместо public A a = null; написать public A a = new A(); — выкинется NotSerializableException.
В данном же случае все будет сериализовываться. При десериализации не вызывается конструктор дессириализуемого класса, но если его родители не реализуют интерфейс Serializable, то у них вызывается конструктор по умолчанию.
Если в этом примере A будет реализоываться Serializable, а не C, то вывод будет 1 2 3
Если в этом примере во всех трех классах убрать конструктор без параметров, то при десериализации выкинется java.io.InvalidClassException: no valid constructor, так как джава пытается вызвать конструктор без параметров у родителя.
3. Введение в заблуждение
Что будет выведено в результате выполнения этого кода?
import java.util.*;
public class Main {
public static List getSorted()
{
List<Integer> sorted = new LinkedList<Integer>();
sorted.add(3);
sorted.add(1);
sorted.add(2);
return sorted;
}
public static final void main(String[] args) throws Exception {
System.out.println(getSorted());
}
}
1. 1 2 3
2. 3 2 1
3. 3 1 2
4. Не скомпилируется
5. Ошибка времени выполнения
Ответ:
3. 3 1 2.
То, что метод и лист внутри метода называются getSorted() и sorted, вовсе не означает, что LinkedList тоже sorted.
4. instanceof
Что будет выведено в результате выполнения этого кода?
class A {
}
class B extends A {
}
class C extends B {
}
class D {
}
public class Main {
public static final void main(String[] args) {
B b = new C();
A a = new C();
D d = new D();
System.out.println(b instanceof A);
System.out.println(a instanceof B);
System.out.println(d instanceof C);
}
}
1. true true false
2. true false false
3. Ошибка компиляции
Ответ:
3. Ошибка компиляции. Так произойдет, потому что D и C находятся на разных ветках иерархии и не приводимы друг к другу.
5. А что за параметр?
public static void print(List<? extends String> list)
{
// сюда можно добавить...
}
1. list.add(«Привет, Хабрахабр!»);
2. list.add(new Object());
3. list = new ArrayList();
4. list = new ArrayList<?>();
5. list = new ArrayList<Objeсt>();
Ответ:
3. list = new ArrayList();
Всё логично: вдруг к нам придет List<Т>, где T и правда наследуется от String?.. Тогда при вызове list.add(«Привет, Хабрахабр!»); джава просто не сможет сделать преобразование типов. Понимая это, компилятор компилироваться коду со строкой '1' не даёт. С 2, 4, 5 — тоже всё понятно. list = new ArrayList(); — корректный код.
6. Исключения и переопределение метода
Что будет выведено в результате выполнения этого кода?
class A {
public void print() throws Exception {
throw new Exception();
}
}
class B extends A {
public void print() {
System.out.println("B");
}
}
public class Main {
public static final void main(String[] args) {
B b = new B();
b.print();
}
}
1. B
2. Ничего
3. Ошибка компиляции
4. Exception
Ответ:
Переопределяющий метод не должен бросать новое или более широкое по классу исключение. Не бросать его вообще он может. Так что код скомпилируется и выведет B.
7. Исключения и переопределение метода — 2
Что будет выведено в результате выполнения этого кода?
class A {
public void print() throws Exception {
throw new Exception();
}
}
class B extends A {
public void print() {
System.out.println("B");
}
}
public class Main {
public static final void main(String[] args) {
A a = new B();
a.print();
}
}
1. B
2. Ничего
3. Ошибка компиляции
4. Exception
Ответ:
3. Ошибка компиляции.
Так как мы в классе A объявлено исключение, а в main(...) мы его не обрабатываем. Тип возвращаемого значения (который может быть не таким, как в суперклассе, ведь есть covariant return) и выбрасываемые исключения проверяются компилятором по типу ссылки.
8. Integer++?
Как можно изменить класс A, чтобы не повлиять на клиентский класс?
class A {
private int i = 0;
public void add(int i)
{
update(++i);
}
private void update(int i)
{
this.i = i;
}
}
public class Main {
public static final void main(String[] args) {
new A().add(5);
}
}
1. Заменить ++i на i++
2. Заменить public void add(int i) на private void add(int i)
3. Заменить public void add(int i) на public void add(Integer i)
4. Ничего из вышеперечисленного
Ответ:
3. Заменить public void add(int i) на public void add(Integer i)
Просто нужно знать, что ++ и -- работает и с Integer. И с Double. И с Float. И со всеми численными обертками.
Читайте статьи, практикуйтесь. И всё получится. Сложного в этом ничего нет.
Если есть какие-то вопросы об экзамене, отвечу в комментариях.