Время на прочтение
7 мин
Количество просмотров 91K
В этой статье речь снова пойдет о сертификации. Не так давно я рассказывал о процессе получения сертификата от компании Google для Android разработчиков. Почитать об этом можно вот здесь. В статье я периодически приводил сравнение с процессом получения сертификатов от Oracle. Немного подумав, я решил раскрыть эту тему подробнее, благо сертификат от Oracle я получил полгода назад и еще не все забыл. Естественно, на хабре уже не раз описывали этот процесс. Например, достаточно подробные описания можно найти тут и тут. Однако, указанные статьи были написаны несколько лет назад, и затрагивают Java SE 7. Я же постараюсь сосредоточиться на особенностях экзамена по Java SE 8 и в принципе обновить информацию по процессу получения сертификата. Тех, кому все еще интерсено, прошу под кат.
Разновидности сертификатов
Итак, по какой-то причине вы решили стать не просто Java разработчиком, а сертифицированным Java разработчиком. За сертификатом мы естественно отправимся к Oracle. Уж чего-чего, а этого добра у них хватает. Но нас интересуют только сертификаты по Java, в частности Java SE 8. Какие же у нас есть варианты? Посмотреть их можно тут.
На момент написания статьи есть следующие варианты:
Как видно, есть 3 уровня сертификатов:
- Associate
- Professional
- Master
Если это ваш первый сертификат по Java, то ваш путь однозначно приведет вас к Java SE 8 Oracle Certified Associate (OCA) certification. Это самый простой экзамен, но без него (или аналогичных, о чем чуть позже) не получить остальные. Для получения этого сертификата нужно всего лишь сдать экзамен за номером 1Z0-808. Мне его сдавать не довелось, поэтому двинемся дальше.
Если вам уже довелось получать какой-то из сертификатов, то можно двигаться в сторону Oracle Certified Professional Java SE 8 Programmer, о котором собственно эта статья. И вот здесь уже есть следующие варианты:
- у вас есть сертификат Associate Java SE 8
- у вас есть сертификат Programmer Java SE 7
- у вас есть сертификат Programmer Java SE 6 or below
Хочу обратить на этот момент более пристальное внимание. От того, какой у вас сертификат, зависит выбор экзамена, который нужно проходить. А от того, какой экзамен будет выбран, будут зависеть вопросы на этом самом экзамене.
В первом случае нам понадобится экзамен 1Z0-809.
Во втором случае нам понадобится экзамен 1Z0-810.
В третьем случае нам понадобится экзамен 1Z0-813.
Ну и наконец, венец всему, Oracle Certified Master, Java SE 6 Developer. А почему 6, спросите вы, ведь речь идете о Java SE 8. В чем причина я не знаю, но Oracle не собирается выпускать экзамен Master уровня для 8-й Java. По крайне мере в поддержке мне ответили именно так. Вероятно, дело в содержании экзамена. Уровни Associate и Programmer проверяют знание SDK соответствующей версии. В случае Master нужно писать приложение. И в этом случае наверное не так важно, на какой именно Java оно написано. Так же Master является самым дорогим экзаменом — его стоимость неумолимо подкрадывается к 1000$, так как для его получения нужно в обязательном порядке пройти какой-нибудь из обучающих курсов Oracle.
Так уж получилось, что мне подошел третий вариант, так как у меня на руках имелся сертификат по Java SE 6, а семерку я пропустил, так как изменений там было не сильно много. Все, что будет написано дальше, будет относиться именно к получению сертификата Oracle Certified Professional Java SE 8 Programmer путем улучшения его из сертификата по 6-й Java.
Подготовка
Итак, вы определились с тем, какой экзамен вам нужно сдавать и готовы ринуться в бой. Но не советую торопиться. Даже если вы гуру Java, сертификация может преподнести вам много сюрпризов, в основном неприятных.
Что же нужно иметь ввиду? Сертификация проверяет ваши знания SDK, причем разными способами. Где-то просят оценить кусок кода и указать на ошибки. Где-то нужно мысленно запустить программу и определить ее вывод. Где-то нужно дополнить код. В общем вариантов много, но во всех скрывается один главный подвох. Точнее, их два. Нужно определить, скомпилируется ли приведенный кусок кода. В большом количестве вопросов есть вариант ответа, который предполагает, что код не скомпилируется. Если вы используете в работе IDE, то тут могут возникнуть сложности, так как оыбчно именно IDE берет на себя эту задачу. Понадобится некоторое время на то, чтобы это начать делать самому. И тут-то в дело вступает второй подвох — авторы тестов ждут от кандидатов безусловного знания сигнатур методов. Во многих вопросах компиляция не случится именно из-за того, что где-то не соответствует количество параметров, или не тот тип возврата, или метод пытается маскироваться под метод похожего класса.
Все вышеописанное можно обойти достаточно простым способом — потратить некоторое время на подготовку к сертификации. Не на изучении Java, а именно подготовку к сертификации. И как раз сейчас я напишу, как же я готовился с тесту.
Имея опыт подготовки к сертификации и зная, с чем придется столкнуться, я разделил для себя подготовку на 3 части:
- чтение книжки и решение mock задачек
- изучение рекомендаций Oracle
- вольные художества
При подготовке к сертификации по Java 8 основное внимание стоит уделить Stream API и лямбдам. Этого будет много. Так же много будет вопросов про дату, время и связянные с этим вещи. NIO2 тоже будет много. Если вы делаете апгрейд со старой версии Java, то так же будет ряд специфичных вопросов по вещам, которых в этих старых версиях не было. Особенно это касается Java 6 и ранее.
Первая часть достаточно проста. Нам нужно найти книжку, в которой описывается процесс подготовки к сертификации со всеми подробностями. И такая книжка существует. Они есть для разных версий Java и разных уровней сертификации. В моем случае понадобилась книжка «Java OCP 8 Programmer II Study Guide» за авторством Jeanne Boyarsky и Scott Selikoff. В ней очень подробно и хорошо расписан процесс подготовки. Содержимое разбито на части, к каждой из которых прилагаются 10-20 проверочных задачек. Так же на специальном сайте, ссылка на который есть в конце книжки, можно пройти 3 проверочных экзамена.
Моя схема подготовки была следующая. Я прочитал книжку от начала до конца, попутно решая задачки в конце каждой части. После этого прошел 1-й из трех экзаменов, набрав ровно проходной бал 63%. Весьма недовольный результатом прочитал книжку еще раз, сосредоточившись на тех частях, в которых набрал меньше всего баллов. Задачки в конце каждой части я также прорешал еще раз. Второй экзамен был получше, по-моему что-то около 70%. После этого я перешел ко второй части подготовки.
Заходим на страничку выбранного экзамена.
Для меня ее интересная часть выглядела так.
Там заходим во вкладку Exam Topics и видим длинный список того, что будет спрашиваться на экзамене. Берем каждый пункт и тщательно препарируем. После прочтения и осознания этого списка вы должны
познать дао
быть в курсе почти любой каверзы со стороны разработчиков.
Вторая часть плавно перетекает в третью. Вооружившись знанием из книжки и знанием того, что будут спрашивать, пробуем писать небольшие кусочки кода по списку. В ходе этого процесса я открыл для себя пяток интересных вещей, две из которых встретились мне на экзамене. Т.е. о них нигде до этого напрямую не было упомянуто. Вдоволь наигравшись с написанием кода, я прошел третий экзамен и получил что-то около 75%. Следует заметить, что проверочные вопросы обычно оказываются сложнее реальных. Поэтому я счел результат удовлетворительным и отправился записывается на экзамен.
Регистрация на сертификацию
Как и прежде, Oracle сотрудничает с сертификационными центрами, которые делают за них всю
грязную
работу по организации теста. Решив не искать добра от добра, я отправился на сайт того центра, где получал первый сертификат. Если вы там не были, нужно будет зарегистрироваться. После чего, скорее всего, нужно будет заполнить профиль. Я это делал 4 года назад, поэтому подробностей не помню. Но с профилем нужно быть аккуратнее. Когда я его создавал, я находился в Росии, и указал имя и фамилию в первой же пришедшей в голову транслитерации. Так как при первой сертификации я предъявлял российский паспорт, особых вопросов это не вызвало. Зайдя в профиль в этот раз, я обнаружил, что данные не совпадают с данными в моем загранпаспорте, которым я пользуюсь ввиду нахождения в другой стране. Чтобы не поиметь проблем в день сертификации, я решил обновить данные. Для этого пришлось пообщаться с техподдержкой, выслать им скан паспорта и совершить еще ряд телодвижений. Заняло это все несколько дней. Так что лучше будьте сразу внимательнее к деталям.
После заполнения профиля можно собственно перейти к назначению даты и места теста. Ищем список авторизованных центров в вашем городе и выбираем понравившийся. К выбору стоит подойти вдумчиво, может даже съездить посмотреть. В каких-то центрах может быть холодно, или жарко, или шумно, или людно, или все что угодно. В моем случае в городе всего один центр, а ехать за 70 км в другой город мне было лениво.
Выбираем доступные дату и время и переходим к оплате. На официальном сайте Oracle стоимость экзамена указана как 245$, но на самом деле цена может немного отличаться от страны к стране. В моем случае она составила 250 евро.
После оплаты должна будет прийти кучка писем, сообщающих разную информацию. Ничего особо ценного я там не нашел. Можно выдохнуть и расслабиться, или продолжить подготовку.
Прохождение теста
В назначенный день отправляемся в центр сдачи. Лучше прийти заранее, так как надо будет заполнить ряд документов и сдать вещи. В моем случае вебкамера почему-то отказывалась распознавать мое лицо. Минут 15 ушло только на то, чтобы сделать фото. На экзамен нельзя брать ничего, от слова совсем. Все, что будет при вас обнаружено, может быть использовано против вас. Мне везло оба раза, что я оказывался в помещении один и мне никто не мешал. Но в принципе у вас могут быть соседи, которые тоже что-то будут сдавать.
На тест отводится около 2 часов, в зависимости от варианта экзамена. Обычно удается управиться быстрее. Все вопросы в тесте с множественным выбором. Если ответов несколько, то говорится, сколько именно. В ходе теста вопросы можно пропускать и отвечать позже. Можно сразу вычеркивать неправильные ответы, чтобы потом было проще выбирать. Если совсем не знаете ответ — выберите хоть что-то. Шансы угадать не такие и маленькие. После того, как все вопросы отвечены, завершаем тест. Раньше сразу показывался результат, теперь надо подождать. Забираем свои вещи и уходим. Если тест сдать не получится, за новую попытку надо будет заплатить полную сумму.
По приходу домой меня уже ждало письмо, в котором сообщалось, что я прошел тест и набрал 86%. Не так и плохо, учитывая то, что 4 года назад я набрал 80% и в общем-то не являюсь большим специалистом по Java, тем более по 8-й части, так как пишу под Android. Проходной балл, как я уже упоминал, 63%. Так же в письме сообщалось, что сертификат будет готов через несколько дней. И действительно, через несколько дней в личной кабинете на сайте Orcale появился новый сертификат.
Выглядит он так.
Так же к сертификату прилагает значок (badge) на каком-то стороннем сайте. Выглядит так. При желании можно заказать себе бумажную копию, что я и сделал. Выглядит точно так же. Пришла по почте в течении 2-3 недель.
Через какое-то время пришло письмо, предлагающее получить бесплатно фуболку Java. Думаю, внимательные читатели уже заметили ее на предыдущих скриншотах. Кто же откажется от халявной футболки? Прислали тоже через 2-3 недели.
Итоги
На этом процесс сертификации можно считать завершенным. Подведем краткие итоги того, что нам понадобится и что мы получим.
Понадобится:
- какой-нибудь предшествующий сертифкат по Java от Oracle
- книжка для подготовки
- время для подготовки
- около 250$ за сдачу теста
- время для сдачи теста
- много терпения, чтобы почувствовать себя компилятором
Получим:
- цифровой сертификат в личном кабинете
- бумажный сертификат
- цифровой значок
- футболку (спешите, предложение ограничено)
- сакральное знание о Java SE 8
Всем, кто решится на это мероприятие, желаю терпения и удачи.
Внимание!
ЦТ Pearson VUE и Certiport приостановили работу на территории Российской Федерации.
В связи с изменением курса рубля по отношению к иностранной валюте актуальную стоимость экзаменов уточняйте у наших операторов по контактным телефонам или электронной почте учебного центра Softline.
Сдача этого экзамена требуется для получения сертификации:
Сертифицированный специалист Oracle (Oracle Certified Associate), Программист Java SE 8.
Количество вопросов: 70
Проходной балл: 65%
Валидация: Этот экзамен был написан для версии Java SE 8.
Формат: Несколько вариантов ответа
Продолжительность: 150
К этому экзамену готовят курсы:
JSE8F — Java SE 8 Fundamentals>>
JSE8P — Java SE 8 Программирование/ Java SE 8 Programming>>
- Отзывы
Ищете экзамены или тестирование Java SE 8 Programmer I / Программист Java SE 8, ступень I по технологиям Oracle? Учебный центр Softline – проверенный бизнес-партнер. Каталог экзаменов УЦ Softline – самый полный и содержит только востребованные специалистами материалы.
Вы можете пройти сертификацию Java SE 8 Programmer I / Программист Java SE 8, ступень I в в Учебном центре Softline. Мы будем рады оказать всестороннюю поддержку! В УЦ Софтлайн есть онлайн-экзамены Oracle от Oracle, а также очные занятия.
Как итог сдачи экзамена Java SE 8 Programmer I / Программист Java SE 8, ступень I вы получите соответствующий документ от компании-производителя, подтверждающий ваш профессиональный уровень знаний.
Каков план действий? Укажите соответствующий экзамен, положите его в корзину, оплатите онлайн и будьте уверены – новые знания обязательно принесут большие перспективы.
Всем привет! В этом году Oracle зарезилил свои экзамены по Java 8 — для сдачи стали доступны Associate (1Z0-808) и Professional (1Z0-809). В этой статье я хочу поделиться опытом прохождения новых экзаменов и подробнее раскрыть встречающиеся темы из восьмой версии. Большая часть будет посвящена Professional, так как он наиболее интересен. Также я не буду поднимать философские вопросы о том, надо ли это вообще — поговорим о технической стороне и о том, как подготовиться к сертификации.
О процедуре заказа уже написано много статей, подробно останавливаться на этом месте смысла не вижу. Регистрируемся на PearsonVUE и Oracle CertView, связываем аккаунты, заказываем, оплачиваем и идем сдавать. Сертификационных центров в Киеве хватает (около десятка), и расписание очень гибкое.
Есть приятный бонус. В этом году Java празднует свое 20-летие, и поэтому во всем мире до конца 2015 года действует скидка 20% на все Java-экзамены. Просто введите промокод «Java20» при оплате на PearsonVUE. Судя по всему, есть возможность заказывать со скидкой на январь 2016.
Oracle Certified Associate (1Z0-808)
Associate — это начальный уровень. Здесь проверяют базовые знания языка. На странице экзамена доступен список тем.
Также можно ознакомиться со списком отличий 7-й и 8-й версий. Если сказать в целом, экзамен по 8 — это такой экзамен по 7, где вас дополнительно спросят о лямбдах и new Date and Time API.
Что есть для подготовки:
— Первая часть книги OCA/OCP Java SE 7 Programmer I & II Study Guide by Kathy Sierra & Bert Bates;
— OCA: Java SE 8 Programmer I Study Guide by Jeanne Boyarsky & Scott Selikoff;
— Очень полезный материал Maurice Naftalin’s Lambda FAQ;
— Java 8 Date and Time.
В практических тестах можно потренироваться на Quizful или выбрать что-нибудь отсюда.
Date and Time
Oracle обожает новый API. Вас ожидают вопросы по основным сущностям пакета java.time.
По факту нужно помнить, что все основные классы являются immutable, и не попадаться на глупых вопросах:
LocalDate localDate = LocalDate.now();
localDate.plus(1, ChronoUnit.DAYS);
В данном случае c оригинальным объектом ничего не произойдет.
То же самое касается Period, ZonedDateTime и других. Никаких родственных связей у этих классов нет (но методы преобразования присутствуют).
LocalDateTime localDateTime = LocalDate.now(); //ошибка компиляции
Ничего суперсложного не будет, просто хорошо почитайте материал и потренируйтесь в IDE.
Лямбды
Здесь также будут базовые вопросы: что это такое, в чём фишка, замените лямбду анонимным классом, перепишите кусок кода с использованием лямбд и так далее. Стоит иметь представление о базовых интерфейсах пакета java.util.function (Consumer, Supplier, Function, Predicate, UnaryOperator).
Также будут вопросы о видимости переменных — в Java 8 появился термин effectively final variable (local variables referenced from a lambda expression must be final or effectively final). Пример:
List<String> list = new ArrayList<>(); list.add("Hi"); list.add("Toast"); list.add("Beer"); int count = 2; list.removeIf((String s) -> s.length() <= count); //1 list.forEach((s) -> System.out.println(s)); //2 if (list.size() == 2) { count = 5; //3 } else { System.out.println("Hello!"); }
В данном случае мы получаем ошибку компиляции в строке 1, так как переменная count изменяется в блоке if и перестает быть effectively final. Если убрать строку 3, всё будет окей. Обратите внимание, что изменение происходит после обращения, но компилятор отслеживает такие вещи. String s в строке 1 не имеет никакого отношения к s в строке 2 — это локальные имена аргументов и разные способы объявления.
Сам экзамен довольно прост. Просто будьте внимательны.
Oracle Certified Professional (1Z0-809)
Он же бывший SCJP. Список тем лежит на странице экзамена. Есть и список отличий 7-й и 8-й версий.
Экзамен появился лишь в августе. В связи с этим есть нюансы — study guide’ы на момент написания статьи отсутствуют. Ближайший релиз ожидается 21-го декабря: OCP: Java SE 8 Programmer II Study Guide by Jeanne Boyarsky & Scott Selikoff.
Как готовиться:
— Материалы по OCA;
— Вторая часть OCA/OCP Java SE 7 Programmer I & II Study Guide by Kathy Sierra & Bert Bates;
— Java SE 8 for the Really Impatient by Cay Horstmann;
— Летом был замечательный курс Oracle JDK 8 Lambdas and Streams. Материалы доступны на YouTube;
— А если и этого мало — Java 8 Stream tutorial;
— Любые mock-тесты. Например, Enthuware 1Z0-809.
Что будет на экзамене? Для начала все классические темы, вопросы по которым «проапгрейджены» с использованием нового синтаксиса и приёмов. Ну и, конечно же, Java 8 (особенно Stream API). О новых темах, которые мне встретились, я и хочу написать ниже.
Optional
Одно из нововведений. Помимо собственной функциональности, активно используется Stream API (reduce, max, min, findAny, etc.). Где искать подвоха и что важно понимать? Optional призван избавить нас от NullPointerException. Так ли это на самом деле?
Optional<String> opt = Optional.of(null);
System.out.println(opt); //и получаем NPE :)
Для избавления существует метод ofNullable. Но и тут есть свой нюанс:
Optional<String> opt = Optional.ofNullable(null); //вернёт Optional.empty
System.out.println(opt.get()); //NoSuchElementException
Почему так было сделано и почему существует of и ofNullable — я нагуглил здесь.
Нельзя изменить контент Optional после создания. Любые манипуляции возвращают новый объект.
Optional<String> optional = Optional.empty(); if (optional.isPresent()) { System.out.println("Yes"); } else { optional.of("Java"); } System.out.println(optional.orElse("Unknown"));
Здесь будет выведено «Unknown» — optional.of(«Java») вернул новый объект, но никуда не присвоил.
Interfaces / Functional Interfaces
Начнем с default/static методов. Есть хороший раздел из Maurice Naftalin’s Lambda FAQ. Со static следует помнить, что в отличии от статических методов класса, статические методы интерфейса не могут быть вызваны через ссылку на объект:
interface One { static void foo() {} } class Alpha implements One { } public static void main(String[] args) { One.foo(); //ок One obj = new Alpha(); obj.foo(); //ошибка компиляции }
Дефолтные методы можно переопределять, но нельзя переопределять статические методы дефолтными и обратно:
interface One { default void foo() { System.out.println("One"); } } interface Two extends One { default void foo() { System.out.println("Two"); } static void foo() { //ошибка компиляции System.out.println("Static Two"); } }
Не стоит пугаться количества функциональных интерфейсов в java.util.function. Основных там не много, и они достаточно хорошо описаны в литературе или документации. Все остальные — это специализации (Bi, Int, Double, Long, etc.). Если почитаете и потренируетесь в IDE, проблем возникнуть не должно.
Если быть невнимательным, можно попасться на чем-то таком:
Function<String> f = name::toUpperCase;
Данный код не скомпилируется, потому что Function<T, R> принимает аргумент и возвращаемый тип. Один аргумент может принимать специализация, например, IntFunction<R> (принимает int, возвращает R).
Еще один пример:
Stream<Double> stream = DoubleStream.of(1, 2, 3).boxed(); UnaryOperator<Integer> unaryOperator = x -> x * 2; stream.map(unaryOperator).forEach(System.out::println);
Получаем ошибку компиляции, потому что map ожидает UnaryOperator<Double>
. Но помимо нормального решения, её можно обойти некоторыми извращенными способами. Например, заменив вызов map(unaryOperator) на map(x -> unaryOperator.apply(Integer.valueOf(x.intValue()))) (не делайте так никогда).
Method / Constructor References
По ссылкам на методы в дополнение к основным материалам также хороший материал есть на Oracle docs.
Гораздо больше можно запутаться в ссылках на конструкторы. Базовое объяснение довольно простое:
Supplier<String> supplier = () -> new String();
превращается в
Supplier<String> supplier = String::new;
Ну и вызываем:
String str = supplier.get();
Другого синтаксиса, например, String():new, String::new(«test«>) быть не может. Это вызовет ошибку компиляции. Но что, если в конструктор требуется передать аргументы? Supplier нам уже не подойдет, его метод T get() ничего не принимает.
Создаем свой (также можно воспользоваться Function):
interface SupplierWithArg<T, U> { T get(U arg); } SupplierWithArg<String, String> supplier = String::new; String str = supplier.get(“Java 8");
В данном случае синтаксис ссылки на конструктор никак не поменялся. Компилятор сам определил, какой конструктор класса String вызвать. В случае отсутствия подходящего конструктора, конечно же, будет ошибка компиляции.
А если аргумент параметризован? Например, у нас есть класс:
class Student { List<String> grades; public Student(List<String> grades) { this.grades = grades; } }
И функциональный интерфейс:
interface SupplierWithParamArg<T, U> { T get(List<U> arg); }
В данном случае Student::new не прокатит, компилятору нужно указать тип. Это можно сделать так:
List<String> grades = Arrays.asList("A", "B", “C"); SupplierWithParamArg<Student, String> supplier = Student::<String>new; Student student = supplier.get(grades);
Stream API
There are 95 methods in 23 classes that return a Stream
Many of them, though are intermediate operations in the Stream interface
71 methods in 15 classes can be used as practical Stream sources
(JDK 8 MOOC Lambdas and Streams)
Самое важное нововведение. Более половины вопросов будет именно об операциях со стримами. И также они будут фигурировать в вопросах на общие темы. Ключевым интерфейсом является Stream<T>
— он содержит практически все методы, которые будут упомянуты ниже.
Теперь о частых ошибках:
— Операции со стримами делятся на intermediate и terminal (в документации всегда можно увидеть, к какому типу относится метод);
— Для отработки стрима необходимы две вещи — source и terminal operation;
— Intermediate-операции «are lazy when possible». Они не выполняются, пока не потребуется результат.
Эти три пункта ведут к следующему:
List<StringBuilder> list = Arrays.asList(new StringBuilder("Java"), new StringBuilder(“Hello")); list.stream().map((x) -> x.append(" World”)); list.forEach(System.out::println);
Выведет:
Java
Hello
Не произошло абсолютно ничего, потому что map является intermediate-операцией, которая добавила преобразование и вернула новый стрим. Но без вызова terminal-операции мы просто «вяжем» свои вычисления до финального результата.
Стоит добавить любую terminal-операцию:
list.stream().map((x) -> x.append(" World”)).count(); // count возвращает кол-во элементов стрима.
и стрим отработает. Объекты листа будут изменены в:
Java World
Hello World
Стрим нельзя использовать повторно, если на нем отработала terminal-операция:
List<StringBuilder> list = Arrays.asList(new StringBuilder("Java"), new StringBuilder("Hello")); Stream<StringBuilder> stream = list.stream().map((x) -> x.append(" World")); long count = stream.count(); Object[] array = stream.toArray(); // java.lang.IllegalStateException
Обратите внимание, что метод close для интерфейса Stream не является terminal-операцией. Он идет от интерфейса AutoCloseable, который наследует BaseStream.
Специализированные версии стримов (DoubleStream, IntStream, LongStream) позволяют уйти от создания лишних объектов и autoboxing/unboxing. Мы работаем напрямую с примитивами. У интерфейса Stream есть соответствующие методы для преобразования — mapToXXX / flatMapToXXX. У специализированных версий метод boxed делает обратное — возвращает Stream<xxx>. Ещё у IntStream и LongStream есть интересные методы range и rangeClosed, генерирующие последовательность значений с шагом 1.
Интересную подборку частых ошибок при работе со стримами можно увидеть здесь.
Например, порядок операций и методы skip, limit:
IntStream.iterate(0, i -> i + 1) .limit(10) .skip(5) .forEach((x) -> System.out.print(x + " "));
Выведет: 5 6 7 8 9.
Меняем местами:
IntStream.iterate(0, i -> i + 1) .skip(5) .limit(10) .forEach((x) -> System.out.print(x + " "));
Получаем: 5 6 7 8 9 10 11 12 13 14.
Short-circuit operations
О чем стоит помнить на экзамене? Методы anyMatch, allMatch, noneMatch принимают Predicate и возвращают boolean. Также в названиях методов заложена механика их работы.
Stream<Integer> values = IntStream.rangeClosed(0, 10).boxed(); values.peek(System.out::println).anyMatch(x -> x == 5);
Будет выведена последовательность от 0 до 5. При x = 5 предикат вернет true, и стрим закончит работу.
Методы findFirst, findAny не принимают аргументов и возвращают Optional (потому что результата может и не быть).
C findAny не всё так просто:
Optional<Integer> result = IntStream.rangeClosed(10, 15) .boxed() .filter(x -> x > 12) .findAny(); System.out.println(result);
Казалось бы, данный код всегда выведет Optional с 13 внутри. Однако, findAny не гарантирует последовательности, он может выбрать любой элемент. Особенно это касается parallel-стримов (для производительности которых он был и создан). Для стабильного результата существует findFirst.
Reduction / Mutable Reduction
Самое простое по этой теме: методы min и max принимают Comparator и возвращают Optional.
За агрегирование результата отвечает reduce. Простейшая его версия принимает BinaryOperator (два аргумента — полученное на предыдущем шаге значение и текущее значение). Возвращает всегда одно значение для стрима, завернутое в Optional.
Например, max может быть заменен на:
.reduce((x, y) -> x > y ? x : y)
Или еще проще
.reduce(Integer::max)
Версия с корнем (identity) аккумулирует вычисление на основе типа корня:
T reduce(T identity, BinaryOperator<T> accumulator))
int sum = IntStream.range(0, 9).reduce(0, (x, y) -> x + y);
Mutable reduction позволяет не просто выдать результат, но и завернуть его в какой-нибудь контейнер (например, коллекцию). Для этого у стрима есть методы collect.
Стоит помнить, что collect в простейшей его версии принимает три аргумента:
<R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
Supplier — возвращает новые инстансы целевого контейнера на текущем шаге.
Accumulator — собирает элементы в него.
Combiner — сливает контейнеры воедино.
Пример collect для ArrayList в роли контейнера:
List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
Также был добавлен класс Collectors с множеством уже реализованных удобных операций. Рассмотрите его методы и хорошенько поиграйтесь в IDE. Например, по groupingBy вопросов будет достаточно. Пример:
List<String> list = Arrays.asList("Dave", "Kathy", "Ed", "John", "Fred"); Map<Integer, Long> data = list.stream() .collect(Collectors.groupingBy(String::length, Collectors.counting())); System.out.println(data);
Напоминает GROUP BY из SQL. Метод группирует значения по длине строки и данная его версия возвращает Map. Получаем вывод: {2=1, 4=3, 5=1}.
Ещё есть интересный метод partitioningBy. Он организует элементы согласно предикату в Map<Boolean, List<T>>
:
Stream<Integer> values = IntStream.rangeClosed(0, 10).boxed(); Object obj = values.collect(Collectors.partitioningBy(x -> x % 2 == 0)); System.out.println(obj);
Вывод:{false=[1, 3, 5, 7, 9], true=[0, 2, 4, 6, 8, 10]}
Parallel streams
По этой теме вопросов откровенно мало. Не волнуйтесь, вас и так будут спрашивать по многопоточности и Fork/Join Framework. По последнему может начаться настоящий трeш и угар. От простых вопросов: «Что это такое? Преимущества?» и «RecursiveTask vs RecursiveAction» до огромных полотен кода с сортировками массивов.
Под капотом параллельных стримов как раз и работает ForkJoinPool.
Для начала — методы parallel / sequential являются intermediate-операциями. С их помощью можно определять тип операций. Стрим может переходить из sequential в parallel и обратно. По-дефолту Collection.stream возвращает sequential-стрим.
List<Integer> list = IntStream.range(0, 256).boxed().collect(Collectors.toList()); int sum = list.stream() .filter(x -> x > 253) .parallel() .map(x -> x + 1) .sequential() .reduce(Integer::sum).orElse(0);
forEachOrdered наряду с forEach существует не просто так.
Например:
IntStream.range(0, 9).parallel().forEach(System.out::println)
Будут выведены числа от 0 до 8 в непредсказуемом порядке. Метод forEachOrdered заставит вывести их в натуральном порядке. Но он не сортирует данные (if the stream has a defined encounter order © JavaDoc).
Еще нюанс — далеко не факт, что параллельный стрим всегда заставит вычисления обрабатываться в разных потоках:
List<String> values = Arrays.asList("a", "b"); String join = values.parallelStream() .reduce("-", (x, y) -> x.concat(y)); System.out.println(join);
Если тут случится распараллеливание, и результат будет обрабатываться в двух разных потоках, на выходе получим —a-b. Каждый элемент по отдельности сольется с корнем, а затем всё сольется воедино. Но этого может и не произойти, тогда на первом шаге получим -a, а финальным результатом будет -ab.
Collections
Наиболее видимые изменения: Iterable и Map получили forEach. Обратите внимание, что для Map он принимает BiConsumer (два аргумента для ключа и значения):
Map<Integer, String> map = new HashMap<>(); map.put(1, "Joe"); map.put(2, "Bill"); map.put(3, "Kathy"); map.forEach((x, y) -> System.out.println(x + " " + y));
Кстати, можно вполне себе выводить, например, только значения. Не обязательно использовать все аргументы в выражении — map.forEach((x, y) -> System.out.println(y));
Далее, Collection получил stream() и parallelStream().
Могут попасться теоретические вопросы на тему работы HashMap. HashMap, LinkedHashMap, ConcurrentHashMap ведут себя иначе в Java 8. Грубо говоря, когда с хэшами беда и количество элементов связного списка в корзине переваливает за определенное значение, то список превращается в сбалансированное дерево. Об этом можно почитать, например, здесь или здесь.
Date and Time
Здесь придется углубиться в функционал новых классов. Duration манипулирует датами в разрезе часов/минут/секунд. Period использует дни/месяцы/годы. Где будет видна эта разница больше всего? При смещении временных диапазонов и переходом на летнее/зимнее время.
Например, в этом году в Украине переход на зимнее время состоялся 25 октября в 4 часа ночи (на час назад):
LocalDateTime ldt = LocalDateTime.of(2015, Month.OCTOBER, 25, 3, 0); ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("EET")); zdt = zdt.plus(Duration.ofDays(1)); System.out.println(zdt); zdt = ZonedDateTime.of(ldt, ZoneId.of("EET")); zdt = zdt.plus(Period.ofDays(1)); System.out.println(zdt);
Данный код выведет:
2015-10-26T02:00+02:00[EET]
2015-10-26T03:00+02:00[EET]
Что произошло? Duration добавил к дате конкретные 24 часа (потому что длительность одного дня всегда 24 часа). При переходе получаем на час меньше. Period же добавил конкретный день, и локальное время сохранилось.
I/O, NIO 2
Касаемо общих вопросов, стоит хорошо ориентироваться в операциях Path — normalize, relativize, resolve. А также StandardOpenOption. Но об этом будет достаточно в рекомендуемой литературе.
Теперь о Java 8. Вас могут ожидать не очень сложные вопросы про чтение и обработку текстового файла. В Files и BufferedReader появился метод lines(), возвращающий стрим, который состоит из строк выбранного файла.
Например, вывести строки:
Files.lines(Paths.get(“file.txt”)).forEach(System.out::println);
Или — разбить на слова, убрать дубликаты, перевести в нижний регистр и отсортировать по длине:
try (BufferedReader reader = Files.newBufferedReader( Paths.get("file.txt"), StandardCharsets.UTF_8)) { List<String> list = reader.lines() .flatMap(line -> Stream.of(line.split("[- .:,]+”))) .map(String::toLowerCase) .distinct() .sorted((w1, w2) -> w1.length() - w2.length()) .collect(Collectors.toList()); }
Кроме этого, в классе Files стримы также используют методы list, find и walk.
Заключение
Надеюсь, я смог немного раскрыть встречающиеся темы. К сожалению, исключительно из личного экзаменационного опыта нельзя описать всё возможное.
Еще несколько общих советов:
— Не нервничайте:). Вопросы в целом адекватные и без извращений. У Oracle нет цели завалить вас кривыми тестами;
— Также стоит следить за временем. На оба экзамена дается 2,5 часа. Лично у меня на OCA еще оставалось минут 40 на перепроверку, а вот в случае с OCP — около 15-ти;
— При подготовке посвящайте больше времени практике — это даст куда больше зазубривания книг. Открывайте IDE и пробуйте любые непонятные вещи.
Удачи!
Белорусско-Савеловский
3-я ул. Ямского Поля, д. 32, 1-й подъезд, 5-й этаж
Радио
ул. Радио, д.24, корпус 1, 2-ой подъезд, 2-ой этаж
Таганский
ул. Воронцовская, д. 35Б, корп.2, 5-ый этаж
Бауманский
ул. Бауманская, д. 6, стр. 2, бизнес-центр «Виктория Плаза», 4-й этаж
Теги: сертификация, oracle java programmer (ocajp)
Сертификация Oracle Java Programmer (OCAJP) позволит вам получить официальное звание Oracle Java Programmer, которое, безусловно, украсит ваше резюме. В этой статье мы составили перечень материалов, которые помогут при подготовке к сдаче этого ответственного экзамена.
Стоит отметить, что если вы всё же решились на этот шаг, не стоит недооценивать коварность составителей тестов. А значит, будьте готовы потратить личное время на подготовку.
Согласно официальной странице сайта Oracle, наиболее популярными экзаменами по Java SE до сих пор остаются:
— Java SE 8 Programmer I (Exam Number: 1Z0-808);
— Java SE 8 Programmer II (Exam Number: 1Z0-809).
Соответственно, речь идёт об экзаменах первого и второго уровня. Первая часть относительно проста и требует базового понимания JavaCore и ООП, однако встречаются как вопросы на внимательность, так и хитрые формулировки. Вторая часть заметно сложнее — для успеха вам потребуется более глубокое знание Java. Есть много вопросов по Stream API (до 40 %), в том числе и вопросы по знанию всех intermediate- и terminal-методов. Также надо будет знать все функциональные интерфейсы с точными сигнатурами их методов, причём наизусть. Могут встретиться и вопросы про смену летнего времени на зимнее в LocalDateTime. Некоторые экзаменуемые пишут, что только около 30 % вопросов связаны с пониманием, а порядка 70 % — это, по сути, вопросы на заучивание методов API из Javadoc.
Интересный момент: в связи с пандемией сдавать экзамен сегодня можно в режиме онлайн.
Для эффективной подготовки рекомендуют много материалов, лучшие из которых мы собрали в один список. Некоторые из материалов уже не новы, но до сих пор полезны. Необязательно изучать все из них — лучше выбрать наиболее подходящий и работать с ним каждый день.
Книги:
- «OCA Java SE 8 Programmer I Certification Guide», автор — Мала Гупта (Mala Gupta). Охватываются вопросы, необходимые для сдачи экзамена OCA Java SE 8 Programmer I Certification (код 1Z0-808). В книгу включён и полномасштабный пробный экзамен.
- «OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam 1Z0-808» — Жанна Боярски (Jeanne Boyarsky), Скотт Зеликофф (Scott Selikoff). Прекрасная книга для подготовки к экзамену OCAJP8, представляющая собой наиболее полное изложение вопросов OCAJP8. Начинается с теста для проверки своих знаний и включает в себя много примеров для изучения как новых, так и старых принципов Java.
- «OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide: Exam 1Z0-809» — те же авторы, но речь идёт уже о втором экзаменационном уровне.
- «OCA Java SE 8 Programmer I Study Guide (Exam 1Z0-808)». Содержит сведения от первоисточника, то есть Oracle. 3-е издание написано Эдвардом Финеганом (Edward Finegan) и Робертом Лигуори (Robert Liguori). Можно неплохо попрактиковаться, т. к. есть много упражнений и компакт-диск с двумя полномасштабными пробными экзаменами.
- «Oracle Java SE8 Programmer Exam Self-Practice Review Questions for Exam 1z0-808». Книга для отработки вопросов экзамена OCAJP8. Включает в себя более 120 вопросов для тренировки. Может использоваться для повышения качества подготовки вместе с любой из вышеназванных книг.
Также для подготовки рекомендуют:
- Тренажеры enthuware: 1Z0-808 JA+V8, 1Z0-809 JQ+V8.
- Форум CodeRanch.
- И, разумеется, туториалы от Oracle.
Есть и ещё один путь подготовки — пройти соответствующий курс в OTUS, который на момент написания материала не имел аналогов в России.
Источники:
— https://javarush.ru/groups/posts/234-luchshie-knigi-dlja-podgotovki-k-ehkzamenu-ocajp8-1z0-808-po-java-8;
— https://vk.com/@java_time-ocpjp-ili-put-dzhedaya;
— https://education.oracle.com/java-and-dev-tech/java-se/product_267?certPage=true.
А какие материалы для подготовки к Java-сертификации рекомендуете вы? Пишите в комментариях!
Код экзамена 1Z0–808 относится к Java SE 8 Programmer I для получения сертификата Oracle Certified Associate, Java SE 8 Programmer Certification. Это программа сертификации начального уровня для программистов Java. Экзамен требует, чтобы вы прошли 65%. Есть 70 вопросов с несколькими вариантами ответов, и вам нужно пройти этот экзамен за 150 минут. Он охватывает изменения Java SE 8 и основные навыки работы с Java, включая концепции объектно-ориентированного программирования, исключения, типы данных, класс String, класс StringBuilder, лямбда-выражения, Java 8 Date/Time API и массивы.
1Z0–808 Syllabus
Следующее содержание взято непосредственно с официальной страницы 1Z0–808 от Oracle.
Основы Java
Определение области действия переменных
Определение структуры класса Java
Создание исполняемых приложений Java с помощью основного метода; запустить программу Java из командной строки; производить консольный вывод
Импортировать другие пакеты Java, чтобы сделать их доступными в вашем коде
Сравните и сопоставьте функции и компоненты Java, такие как: независимость от платформы, объектная ориентация, инкапсуляция и т. д.
Использование операторов и конструкций принятия решений
Используйте операторы Java; используйте круглые скобки для переопределения приоритета оператора
Проверяйте равенство между строками и другими объектами, используя == и equals ()
Создайте if и if/else и троичные конструкции
Используйте оператор switch
Использование циклических конструкций
Создание и использование циклов while
Создание и использование циклов for, включая усовершенствованный цикл for
Создание и использование циклов do/while
Сравнение конструкций циклов
Использование разрыва и продолжения
Работа с наследованием
Описывать наследование и его преимущества
Разрабатывать код, использующий полиморфизм; разработать код, переопределяющий методы; различать тип ссылки и тип объекта
определять, когда необходимо приведение типов
использовать super и this для доступа к объектам и конструкторам
использовать абстрактные классы и интерфейсы
Работа с выбранными классами из Java API
Управление данными с помощью класса StringBuilder и его методов
Создание строк и управление ими
Создание данных календаря и управление ими с помощью классов из java.time.LocalDateTime, java.time.LocalDate, java.time.LocalTime, java.time .format.DateTimeFormatter, java.time.Period
Объявите и используйте ArrayList заданного типа
Напишите простое лямбда-выражение, использующее выражение лямбда-предиката
Работа с типами данных Java
Объявлять и инициализировать переменные (включая приведение типов данных-примитивов)
Различать переменные-ссылки на объекты и переменные-примитивы
Уметь читать или записывать в поля объектов
Объяснять жизненный цикл объекта (создание, «разыменование» путем переназначения» и сборки мусора)
Разработайте код, использующий классы-оболочки, такие как Boolean, Double и Integer.
Создание и использование массивов
Объявление, создание экземпляров, инициализация и использование одномерного массива
Объявление, создание экземпляров, инициализация и использование многомерных массивов
Работа с методами и инкапсуляцией
Создавайте методы с аргументами и возвращаемыми значениями; включение перегруженных методов
Применение ключевого слова static к методам и полям
Создание и перегрузка конструкторов; различать конструкторы по умолчанию и пользовательские конструкторы
применять модификаторы доступа
применять принципы инкапсуляции к классу
определять влияние на ссылки на объекты и примитивные значения, когда они передаются в методы, которые изменяют значения
Обработка исключений
Различать проверенные исключения, непроверенные исключения и ошибки
Создать блок try-catch и определить, как исключения влияют на нормальный ход программы
Описать преимущества обработки исключений
Создать и вызвать метод, который создает exception
Распознавание общих классов исключений (таких как NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException)
Где взять учебные материалы 1Z0–808?
Я предпочитаю учебные планы MyExamCloud, и они предлагают практические тесты для всех этих сертификатов. Вы можете найти список сертификатов Java на этой странице. https://www.myexamcloud.com/onlineexam/collection/javacertification
Сертифиĸация помогает понять, струĸтурировать и заĸрепить знания по Java. Праĸтиĸа поĸазала, если есть цель получить сертифиĸат – обучение идет гораздо эффеĸтивнее и быстрее. Помимо этого, на собеседованиях можно поĸазать сертифиĸат работодателю и его наличие будет хараĸтеризовать вас ĸаĸ человеĸа целеустремленного, ĸоторый способен работать с большими объемами информации.
В ноябре 2020 я сдал эĸзамен Oracle Certified Professional Java 11 1Z0-819. Для меня это была долгая дорога длиною в 4 месяца. У меня был довольно сĸудный опыт в Java.
Я прочитал ĸнигу «Философия Java», «Струĸтуры данных и алгоритмы Java», прошел до 20 уровня на javarush. Но реального опыта и постоянной праĸтиĸи у меня не было, поэтому, даже решая задачĸи на leetcode, я то и дело встречался с ситуацией, ĸогда не понимал, ĸаĸ лучше обработать строчĸу или ĸаĸ преобразовать массив из Integer в int и обратно.
Все это ĸажется довольно простыми задачами, но не имея реального опыта работы с языĸом, невозможно прочитать и запомнить все методы того или иного ĸласса.
По этой и по ряду других причин я решил, что мне нужно сдать эĸзамен. По правде говоря, готовиться я начал ĸ эĸзаменам 1Z0-808 и 1Z0-809. Готовился я по ĸнигам Jeanne Boyarsky and Scott Selikoff. Книги написаны информативно и не сĸучно, таĸ что осилить первую ĸнижĸу особого труда не составило. Книги на английсĸом, перевода вроде бы нет, да смысла в нем тоже, таĸ ĸаĸ сам эĸзамен таĸже проходит на английсĸом.
Прочитав первую ĸнигу до ĸонца, я решил разобраться с тем, ĸаĸим же образом я могу сдать эĸзамен. Погуляв по сайту Oracle я понял, что могу сдать эĸзамен по Java 11, а именно эĸзамен 1Z0-815. Разница между 1Z0-808 и 1Z0-815 оĸазалась несущественной. Все, что необходимо было знать – это модули, ĸоторые появились в Java 9.
Изучая тему модулей еще с недельĸу я решил, что пришла пора сдать эĸзамен. Однаĸо натĸнулся на новость о том, что с оĸтября (а это было через 2 месяца) два эĸзамена 1Z0-815 и 1Z0-816 перестанут существовать и их заменит один эĸзамен 1Z0-819. С одной стороны – это ĸруто, можно сэĸономить 150 долларов за сертифиĸат (для получения сертифиĸата необходимо сдать оба эĸзамена).
С другой стороны, условия эĸзамена стали сложнее, чем были до этого. В ĸаждом из предыдущих четырех эĸзаменов (1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816) давалось 150 минут и 70 вопросов. В новой же версии эĸзамена 90 минут и 50 вопросов. Количество тем в эĸзамене в два раза больше, чем в предыдущем варианте. Настоящие герои не ищут легĸих путей, поэтому я решил сдать единый 1Z0-819.
Я начал строить для себя mindMap с темами эĸзамена и всеми вопросами, ĸоторые могут ĸасаться этой темы. Прочитав обе ĸниги (1Z0-808 и 1Z0-816), я собрал полную ĸарту эĸзамена. Основные темы ĸарты почти соответствовали темам в ĸниге.
На изображении видна сама ĸарта и вопросы ĸ ней. Вопросы мне задавала жена дважды в день. Все. Поĸа мы ехали за продуĸтами, за завтраĸом, во время прогулĸи. Постоянно. После прочтения ĸниг я начал сдавать пробные эĸзамены. Сдавал я их тут.
По проценту правильных ответов можно видеть, ĸаĸ моя вера в себя то росла, то падала, ĸаĸ на америĸансĸих горĸах. Кроме того, моя ĸомпания оплачивала получение сертифиĸата тольĸо в случае сдачи на 80% и выше. Это была моя мотивация сдать на 80 баллов.
Незадолго до сдачи эĸзамена я прочитал, что один из авторов ĸниг сдал эĸзамен на 72 балла, а второй на 87 баллов, от этого я немного взгрустнул, таĸ ĸаĸ если автор данных ĸниг сдал тольĸо на 72 балла, то на 80 у меня вряд ли получится…
Про ĸонцентрацию сĸажу ещё раз отдельно – я не знаю, возможно ли при сдаче эĸзаменов поймать состояние потоĸа, ĸаĸ при ĸодинге, но у меня ни разу не получилось. Сидеть с полной ĸонцентрацией полтора часа оĸазалось для меня настоящим испытанием.
Чуть-чуть расслабишься – пропустишь ошибĸу в ĸоде, ĸоторая влияет на правильный ответ. Поэтому надо стараться проходить пробные эĸзамены без пауз, с таймингом и маĸсимальной ĸонцентрацией. «Полный эффеĸт присутствия».
Сдавал я эĸзамен из дома, через pearsonvue. Чтобы сдать эĸзамен, необходимо приобрести ваучер, затем выбрать дату эĸзамена, сĸачать тестовую программу. При запусĸе данная программа проверяет, чтобы на вашем ĸомпьютере не было отĸрыто ничего другого, ĸроме этой самой программы. Видео/аудио связь – само собой.
При сдаче эĸзамена также необходимо будет поĸазать доĸумент, подтверждающий вашу личность. Обязательно сверьте, что в вашем профиле на oracle и pearsonvue ваши имя/фамилия были один в один, ĸаĸ в доĸументе. Я использовал загранпаспорт, таĸ ĸаĸ в нем имя/фамилия на латинице.
Смотреть на эĸзамене в сторону нельзя, ниĸаĸого постороннего шума, ниĸаĸих листочĸов, тетрадей и т. д. Если нужно что-то где-то написать – в приложении есть встроенный блоĸнот. Он жутĸо неудобный, но выбирать не приходится.
День эĸзамена. Послушав час Эминема, я был морально готов сдавать эĸзамен. Жена уехала в зал, чтобы ничего не могло меня отвлечь. Забавный момент, что в ĸвартире оставалась ĸошĸа, ĸоторая решила именно в тот момент, ĸогда я приступил ĸ сдаче эĸзамена, проверить, может ли она бегать по ĸвартире со сĸоростью звуĸа и ĸаĸой уровень шума она может поднять прежде, чем я на нее отреагирую.
За 12 лет она таĸ ниĸогда себя не вела, поэтому в данном случае это была чистой воды «подстава» с ее стороны.
Вернемся ĸ эĸзамену. Проверив мои доĸументы и спросив, ĸаĸ мои дела, мне дали отмашĸу, что я могу приступать ĸ сдаче. Тяжелее всего было именно отсидеть полтора часа с маĸсимальной ĸонцентрацией. В ĸаĸие-то моменты мозг просто выĸлючался и не пытался найти ответ в ĸоде.
Я боролся с таĸими моментами и двигался дальше. В итоге эĸзамен я сдал ровно на 80 баллов, аж прослезился от счастья, таĸ ĸаĸ ни один пробный я не сдал таĸ хорошо.
Советы:
- При изучении теории старайтесь понять, зачем авторы языĸа поступили подобным образом. Например, overriding rules для методов ĸласса:
- Не торопиться, если ĸажется, что ответ на вопрос сразу известен.
- Все перепроверить. При взгляде на ĸод вспомнить все возможные темы, для ĸаждой пройтись по чеĸ-листу (например, те же overriding rules для методов, см. изображения выше).
- Концентрация – добро, самоуверенность – зло. Каĸ тольĸо начало получаться сдавать тестовые эĸзамены, я почувствовал уверенность в себе и начал их заваливать. Важно всегда быть маĸсимально сĸонцентрированным и не поддаваться этому чувству.
Спасибо всем, ĸто дочитал до ĸонца. Надеюсь, эта информация поможет вам при подготовĸе. Удачи на эĸзамене!
Фото на обложке: pixabay.com