26 October 2011

Java сертификация. Подготовка к SCJP

Java
В этом месяце я сдавал экзамен SCJP. В этом топике я расскажу о подготовке и экзамене.
В основном для тех, кто собирается сдавать и кому нужно больше информации об этом.

Уточнение


Так как Sun'a больше нет, то и экзамена SCJP тоже нет. Теперь он значится так:
1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam.


Подготовка


Подготовка заняла две недели. Использовал только эти источники:

Чтобы попробовать себя, есть еще такие ресурсы:
  • 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. И со всеми численными обертками.

Читайте статьи, практикуйтесь. И всё получится. Сложного в этом ничего нет.
Если есть какие-то вопросы об экзамене, отвечу в комментариях.
Tags:SCJP1Z0-851задачиjavaзадротство
Hubs: Java
Comments 43
Ads
Popular right now