Мои ответы на вопросы собеседований из 40 уровня

Собственно, такие вопросы были на этом уровне:
1. Что такое IP-адрес?
2. В чем отличие host и domain?
3. Какие методы в HTTP вы знаете
4. Чем отличаются методы GET, POST и HEAD?
5. Что такое REST?
6. Зачем нужен класс Calendar в Java?
7. Как преобразовать дату в Java к нужному формату?
8. В чем отличие URI и URL?
9. Что такое сокеты?
10. Отличие классов Socket и URL?

А вот мои ответы:
1. IP-адрес — это уникальный сетевой адрес узла в компьютерной сети, построенной на стеке протоколов TCP/IP. В сети Интернет требуется глобальная уникальность адреса; в случае работы в локальной сети требуется уникальность адреса в пределах сети. В версии протокола IPv4 IP-адрес имеет длину 4 байта, а в версии протокола IPv6 IP-адрес имеет длину 16 байт. Обычно IP-адрес в версии протокола IPv4 записывают в виде четырёх десятичных чисел со значениями от 0 до 255, разделённых точкой, например, 192.168.0.3.

2. Домен — это адрес сайта или определённая зона, которая имеет своё имя, не похожее ни на какое другое имя в системе доменных имён. Домены бывают первого уровня, второго уровня, третьего уровня и т.д. Обычно домен первого уровня не доступен обычным пользователям для регистрации (примеры доменов первого уровня — ".ru", ".com", ".net"). Обычно домены третьего и следующих уровней называют субдоменами.
Хост — это определённый компьютер или сервер, подключенный к локальной или глобальной сети. Хост обладает обладает уникальным адресом в среде сервисов TCP/IP (IP-адресом).

3.GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH, TRACE, LINK, UNLINK, CONNECT.

4.

                        GET	POST	HEAD
---------------------------------------------
Тело Запроса            Нет	Есть	Нет
Тело Ответа             Да	Да	Нет
Кеширование
результата Запроса      Да	Нет	Да, заголовки	
Идемпотентность         Да	Нет	Да


Метод GET используется для запроса содержимого указанного ресурса. Метод POST применяется для передачи пользовательских данных заданному ресурсу. Метод HEAD обычно применяется для извлечения метаданных, проверки наличия ресурса (валидация URL) и чтобы узнать, не изменился ли он с момента последнего обращения. Метод HEAD аналогичен методу GET, за исключением того, что в ответе сервера отсутствует тело. Метода GET считает упрощённой версией POST, потому как метод GET не предполагает полноценного запроса, только URL в качестве такового.

5. REST — это архитектурный стиль взаимодействия компонентов распределённого приложения в сети. Термин был введён Роем Филдингом в 2000 году. Также им были введены требования, которым должно удовлетворять распределённое приложение, чтобы соответствовать архитектуре REST (такие приложения ещё называют RESTful). Вот эти требования:
1) Модель «Клиент-Сервер» (означает, что сеть должна состоять из клиента и сервера; сервер — это тот, кто обладает ресурсами, клиент — тот, который их запрашивает))
2) Отсутствие состояния (означает, что ни клиент, ни сервер не отслеживают состояния друг друга)
3) Кеширование (клиенты и промежуточные узлы могут кешировать результаты запросов; сооответственно, ответы сервера должны иметь явное или неявное обозначение, что они кешируемые или некешируемые)
4) Единообразие интерфейса (означает, что между клиентами и серверами существует общий язык взаимодействия, который позволяет им быть заменяемыми или изменяемыми, без нарушения целостности системы):
а) Определение ресурса (означает, что каждый ресурс должны быть обозначен постоянным идентефикатором)
б) Управление ресурсами через представление (означает, что клиент хранит ресурс в виде его представления, и при желании изменения ресурса он отправляет серверу информацию о том, в каком виде он хотел бы видеть этот ресурс; сервер же рассматривает этот как запрос как предложение, и сам решает, что делать ему с хранимым ресурсом)
в) Самодостаточные сообщения (каждое сообщение содержит достаточно информации, чтобы понять, как его обрабатывать)
г) Гипермедиа (означает, что клиенты изменяют состояние системы только через действия, которые динамически определены в гипермедиа на сервер)
5) Система слоёв (означает, что в системе может быть больше двух слоёв (клиент и сервер), и при этом каждый такой слой знает только о своих соседних слоях, и не знает об остальных слоях, и взаимодействует только с соседними слоями)
6) Код по требованию (означает, что функциональность клиента может быть расширения за счёт загрузки кода с сервера в виде апплетов или сценариев)

Удовлетворение этим требованиям позволяет добиться следующего:
* Надёжность
* Производительность
* Масштабируемость
* Прозрачность взаимодействия
* Простота интерфейсов
* Портативность компонентов
* Лёгкость внесения изменений
* Способность эволюционировать, приспасабливаясь к новым требованиям

6. Он нужен для более удобной работы с датой и временем. Он позволяет работать с датой в рамках календаря, то есть позволяет прибавлять и отнимать дни от какой-то конкретной даты, причём будут учитывать и високосные года. Кроме того, он позволяет представить время миллисекундах в удобном виде — год, месяц, день, часы, минуты, секунды. Также есть много методов для установки и получения разных параметров даты и времени, например: день недели, день месяца, день в году, номер недели в месяце, номер недели в году.

7. Для этого существует удобный класс SimpleDateFormat. Экземпляру этого класс можно передать шаблон представления даты, и тогда он в таком виде будет возвращать дату (в формате строки String), либо считывать дату (из строки String). Выглядит это всё следющим образом:
Date date = new Date(); // получаем текущую дату
SimpleDateFormat formatter = new SimpleDateFormat(«d-MM-yy HH:mm:ss»); //создаём экземпляр класса SimpleDateFormat
//и передаём ему шаблон представления даты и времени
String dateAsString = formatter.format(date); //преобразуем дату в строку заданного формата

Date dateAfterConversion = formatter.parse(dateAsString); //преобразуем строку обратно в дату

8. URI расшифровывается как Uniform Resource Identifier и переводится как «унифицированный идентификатор ресурса». URI — это последовательность символов, идентифицирующая абстрактный или физический ресурс. URL расшифровывается как Uniform Resource Locator. То есть это некий унифицированный указатель на ресурс, однозначно определяющий его месторасположение. URL служит стандартизированным способом записи адреса ресурса в сети Интернет.
Их отличия в том, что URI — это некоторый идентификатор ресурса, который позволяет этот ресурс как-то идентифицировать, а URL — это указатель на ресурс, он даёт информацию о том, где находится ресурс. Таким образом URL — это URI, который помимо индетификации ресурса, даёт информацию о его местонахождении.

9. Сокеты — это связка IP-адрес + порт, позволяющая из внешней сети однозначно идентифицировать программу на компютере или сервере. В Java для работы с сокетами есть два класса Socket и ServerSocket. Экземпляры первого класса играют роль клиента, экземпляры второго — роль сервера. Клиент может отправлять и принимать сообщения через сокет. Сервер же постоянно отслеживает запросы пользователей и отвечает на них.
Для того, чтобы отправить данные через сокет, в классе Socket существует класс getOutnputStream(), возвращающий исходящий поток, с которым уже можно работать как обычно. Для приёма информациию нужно воспользоваться методом getInputStream(), который возвращает входящий поток. Дальше с этим потоком можно работать как с обычно потом ввода. Также стоит отметить, что при создании клиентского сокета (экземпляра класса Socket) в конструктор нужно передать ip-адрес сервера и порт, на котором он работает принимающая программа-сервер.
При создании серверного сокета (экземпляра класса ServerSocket) нужно указывать только порт, через который будет работать программа. После этого вызывается метод accept(). Этот метод ожидание подключение клиента, а после этого возвращает экземпляр класса Socket, необходимый для взаимодействия с этим клиентом. Дальше работать идёт с экземпляром класса Socket, как в первом случае (в случае клиента).

10. Главное отличие в том, что класс URL предназначен для работы с URL-строкой (парсинг URL-строки), а Socket используется для соединения с удалённым сервером и отправки информации на сервер и/или приёма информации от сервера (хотя, используя класс URL, можно получить доступ к ресурсу, на который указывает сам URL; но делается это не напрямую, а через объект класса URLConnection). Также, если смотреть в общем, то Socket используется для связи с сервером (другой программой), а URL — для доступа к ресурсу (например, к файлу). Кроме того, URL и URLConnection ориентированы в основном на работу с HTTP, тогда как Socket может работать с любыми протоколами.

Мои ответы на вопросы собеседований из 38 уровня

Здравсвтвуйте. Опять-таки, похоже нет ответов на вопросы из этого уровня. Поэтому, как обычно, выкладываю свои. Вдруг, кому помогут (или кто-то что-то дополнит или ответит лучше).
Итак, были такие вопросы:
1. Что такое Agile?
2. Что такое Scrum?
3. Какие роли Scrum вы знаете?
4. Что такое спринт? Расскажите с подробностями
5. Кто такие QA?
6. Кто такой product owner?
7. Расскажите об иерархии исключений
8. Что делать если JVM выкинула Error?
9. Какие нововведения в области исключений из Java 7 вы знаете?
10. Зачем нужны аннотации? Как ими пользоваться?

А теперь мои ответы:
1. Agile — это серия подходов к разработке программного обеспечения, ориентированных на использование итеративной разработки, динамическое формирование требований и обеспечение их реализации в результате взаимодействия внутри самооранизующихся рабочих групп, состоящих из специалистов разных профилией. Существует несколько методик, относящих к гибкой методологии разработки, в частности экстремальное программирование, DSDM, Scrum, FDD.

Основные концепции agile-методов:
* люди и взаимодействие важнее процессов и инструментов;
* работающий продукт важнее исчерпывающей документации;
* сотрудничество с заказчиком важнее согласование условий контракта;
* готовность к изменениям важнее следованию первоначального плана.

Также были сформулированы основные приципы такого подхода:
* удовлетвореие клиента за счёт ранней и бесперебойной поставки ценного программного обеспечения;
* приветствие изменений требований даже в конце разработки (это может повысить конкурентноспособность продукта на рынке);
* частая поставка рабочего программного обеспечения (каждый месяц или каждую неделю, или даже ещё чаще);
* тесное, ежедневно общение заказчика с разработчика на протяжении всего проекта;
* проектом занимаются мотивированные личности, обеспеченые нужные условиями работы, поддержкой и доверием;
* рекомендуемый метода передачи информации — личный разговор (лицом к лицу);
* работающее программное обеспечение — лучший измеритель прогресса;
* спонсоры, разработчики и пользователи должны поддерживать постоянный темп на неопределённый срок;
* постоянно внимание улучшению технического мастерства и удобному дизайну;
* простота — искусство не делать лишней работы;
* лучшие технические требования, архитектура и дизайн полуются у самороорганизованной команды;
* постоянная адаптация к изменяющимся условиям.

Основной проблемой разработки было признано то, что никто из участников ни на одном этапе не обладает всей полнотой информации о том, что делать.

2. Scrum — это одна из методик гибкой разработки. Она делает акцент на качественном контроле процесса разработки. Основая особенность скрама — это разбиение процесса разработки на итерации имеющий чёткую протажённость по времени (обычно 2-6 недель; их называют «спринтами»).
В начале спринта проводится «планирование спринта» — совещание на 3-4 часа, где обсуждаются основные задачи, которые будут решаться на протяжении спринта. В конце спринта проводится «демо» — демонтрация результатов работы команды за этот спринт.
Перед самым первым спринтом заказчик (или его представитель) формирует список требований, предъявляемых к будущему продукту. Такие требования называются «user story», а самого заказчика называют «product owner». Также в этом списке заказчик (PO) указывает приоритет для каждой задачи. Сначала будут реализовываться задачи с более высоким приоритетом. Весь список называется «product backlog», или «резерв продукта».
Кроме product owner, среди участников ещё выделяют scrum-мастера: он проводит все совещания, следит за соблюдением всех принципов скрама, разрешает противоречения и защищает команду от отвлекающих факторов. Обычно в качестве скрам-мастера выступает кто-то из команды.
На первом совещании в начале спринта каждой задаче, кроме того, что назчается приоритет, даётся ещё приблизительная оценка в «абстрактных человеко-днях», которые ещё называют «story point». Затем команда решает, сколько она успеет выполнить задач за время спринта. Например, заказчик отобрал 7 задач, а команда сможет сделать только 5. Тогда остальные две задачи пойдут на следующий спринт. Если заказчику это не нравится, он может повысить их приоритет, но тогда другие задачи выпадут из спринта. Кроме того, скрам-мастер может разбить некоторые задачи на более мелкие и расставить им различные приоритеты, чтобы заказчик остался доволен.
Список отобраных задач на спринт называются «sprint backlog», или «резерв спринта». Для лучшей наглядности обычно составляется таблица, в которой указываются задачи, которые нужно реализовать, которые находятся в процессе реализации, и те которые уже выполнены. Также строится диаграмма «сгорания задач». Она графическ показывает, сколько ещё задач осталось выполнить. В идеале график сгорания задач к концу спринта должен опустится до нуля.
Также в течение спринта каждый день или через день проводятся небольшие совещания внутри команды на 5-15 минут, где каждый участник команды рассказывает, что сделал за этот день (или эти два дня), что ещё ему предстоит сделать, а также рассказывает о том, что ему мешает что-то сделать.
Когда спринт завершается, scrum-master проводит demo, на котором демонстрируется список всего, что полностью сделано. Затем проводится «разбор полетов» — совещание тоже на пару часов. На нем обычно пытаются выяснить, что было сделано хорошо, а что (и как) можно было сделать лучше.
Обычно за 2-3 спринта можно выявить основные проблемы, которые мешают команде работать эффективнее, и устранить их. Это приводит к большей продуктивности, не увеличивая нагрузку на команду. Такое было невозможным до эры гибких методологий.
Также в середине спринта, иногда еще проводят «вычесывание» — совещание посвященное планированию следующего спринта. На нем обычно уточняют приоритеты задач, а так же могут разбить некоторые задачи на части и/или добавить новые задачи в product backlog – резерв продукта.

3. В крам участников делят на «свиней» и «кур». «Свиньи» полностью задействованы в процессе, «куры» — только частично. К категории «свиней» относят следующие роли:
* Скрам-мастер (проводит совещания, следит за выполнением принципов скрама и пр.; это кто-то из команды, produst owner не может быть скрам-мастером);
* Владелей продукта (Product Owner) (представляет интересы конечных пользователей и других заинтересованных в продукте сторон);
* Команда разработки (Development Team) (кросс-функциональная команда, состоящая из специалистов разных профилей: разработчиков, тестировщиков, дизайнеров, архитекторов и т.д. Размер команды в идеале составляет от 3 до 9 человек. Команда является единственные полностью вовлечённым участником разработки и отвечает за результат как единое целое. Никто, кроме команды, не может вмешиваться в процесс разработки на протяжении спринта).

К «курам» относятся следующие роли:
* Пользователи (Users)
* Клиенты, продавцы (Stakeholders) (лица, которые инициируют проект и для кого проект будет приносить выгоду. Они вовлечены в скрам только во время обзорного совещания по спринту (Sprint Review));
* Управляющие (Managers) (люди, которые управляют персоналом);
* Эксперты-консультанты (Consulting Experts).

4. Спринт — это одна итерация цикла разработки программного обеспечения в Скраме. Обычно спринт жёстко фиксирован по времени. Продолжительность спринта выбирается на основании размера команды, специфики работы, требований, размера проекта. Чаще всего это подбирается опытным путём, на основании проб и ошибок. В среднем спринт может быть продолжительность от 2 недель до 4 (хотя в некоторых компания его продолжительность бывает равна и 6 неделям). Для оценка объёма работ в спринте может быть использована предварительная оценка, измеряемая в очках истории. Предварительная оценка фиксируется в беклоге проекта.

5. QA расшифровывается как Quality Assuarance (то есть «Гарантия качества», если перевести дословно). К этой категории относятся тестировщики. Это люди, которые выявляют в программе баги и ошибки. Для этого они используют разные средства, как ручные, так и автоматические. После выявления багов и ошибок они сообщают об этом разработчикам, и те исправляют эти ошибки.

6. Product Owner (владелец проекта) — это заказчик или представитель заказчика. Это либо кто-то со стороны клиента (сторонняя фирма или физ.лицо), либо какой-то другой сотрудник фирмы, определящий требования к конечному продукту и следяющий за их выполнений (например, бизнес-аналитик). Как уже было сказано, он определяет требования к продукту и задачи, которые дожна решить команда разработки, чтобы получить конечный продукт. Список требований (или задач) он оформляет в определённым порядке и с заданным приоритетом для каждого требования (задачи). Обычно он участвует в планировании спринта (перед началом спринта) и в демонтрации результатов спринта (после окончания спринта).

7. Во главе иерархии исключений в Java стоит класс Throwable. От не наследуются два класса: Error и Exception. Объекты первого класс выбрасываются, когда возникают какие-то серьёзные ошибки в работе программы и джава-машины в целом (а также в работе ОС и аппаратной части копьютера), так, что программа больше не может продолжать работать и закрывается. Это может быть недостаток памяти (OutOfMemoryError) или переполнение стека (StackOverflowError).
Экземпляры второго класса могут выбраться при самых различных исключительных ситуаций. Собственно от этого класса наследуется класс RuntimeException и все остальные классы. Первый класс так выделяют, потому что, во-первых, исключительные ситуации такого типа являются непроверяемые (unchecked), а, во-вторых, к данным исключительным ситуациям относятся ошибки выполнения программы. Обычно это возникает из-за несовершенства кода. Все остальные исключительные ситуации обычно являются следствием непредвиденного стечения обстоятельств, например, ошибки ввода-вывода.
Также исключения делятся на проверяемые (checked) и непроверяемые (unchecked). Первые необходимо либо отлавливать в блоке try-catch, либо указывать в качестве выбрасываемых в сигнатуре метода (используя слово throws). Непроверяемые этого не требуют, и выбор остаётся за программистом. К проверяемым относятся исключения типа Throwable (а также наследуемые от него) и типа Exception (и наследуемые от него, кроме исключений типа RuntimeException). К непроверяемым относятся исключения типа Error (а также наследуемые от него) и исключения типа Runtime (и наследуемые от него).

8. Ничего, программа просто закроется. Обычно это критические ошибки, не всегда возникшие по вине программиста (например, выход из строя жёсткого диска или сбой операционной системе). Правда, среди них есть две ошибки, которые могу следствием несовершенства кода — это StackOverflowError и OutOfMemoryError. Первый тип ошибок возник, при переполнении стека вызовов — то есть, когда вызывается слишком много методов и стек вызовов становится слишком больший (типичный пример — бесконечная рекурсия или рекурсия с большим количеством итераций). Вторая ошибка — OutOfMemoryError — возникает, когда переполняет память отведённая под объекты, то есть когда создаётся слишком много тяжеловесных объектов, и они все держатся в памяти (или когда сборщик мусора не успевает их уничтожать).

9. В Java 7 в плане исключение были введены три новых «вещи»:
* Multicatching. Это когда в одном catch-блоке сразу обрабатывается несколько исключений:
try {
} catch (Exception1|Exception2|Exception3|… | ExceptionN ex) {}
В таком случае параметр ex будет неявно иметь модификатор final. Кроме того, байт-код, сгенерированный компиляцией такого кода (с единым catch-блоком) будет короче, чем байт-код, сгенерированный компиляцией кода с несколькими catch-блоками.

* Try-with-resources. Эта контрукция позволяет после слова try в скобках указать открываемые ресурсы, которые сами закроются после окончания конструкции try () {} catch{}. В качестве ресурса в данной конструкции может быть использован любой объект, реализующий интерфейс AutoCloseable.
Во время закрытия ресурсов тоже может быть брошено исключение. В try-with-resources добавлена возможность хранения «подавленных» исключений, и брошенное try-блоком исключение имеет больший приоритет, чем исключения, получившиеся во время закрытия. Получить последние можно вызовом метода getSuppressed() от исключения, брошенного try-блоком.

* Rethrowing. Перебрасывание исключений с улучшенной проверкой соответствия типов.
Компилятор Java SE 7 тщательнее анализирует перебрасываемые исключения. Рассмотрим следующий пример:

static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName) throws Exception {
try {
if («First».equals(exceptionName)) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception ex) {
throw e;
}
}

В примере try-блок может бросить либо FirstException, либо SecondException. В версиях до Java SE 7 невозможно указать эти исключения в декларации метода, потому что catch-блок перебрасывает исключение ex, тип которого — Exception.

В Java SE 7 вы можете указать, что метод rethrowException бросает только FirstException и SecondException. Компилятор определит, что исключение Exception ex могло возникнуть только в try-блоке, в котором может быть брошено FirstException или SecondException. Даже если тип параметра catch — Exception, компилятор определит, что это экземпляр либо FirstException, либо SecondException:

public void rethrowException(String exceptionName) throws FirstException, SecondException {
try {
//…
} catch (Exception e) {
throw e;
}
}

Если FirstException и SecondException не являются наследниками Exception, то необходимо указать и Exception в объявлении метода.

10. Аннотации используются для размещения рядом с классом, полем, методом или переменой какой-то дополнительной, служебной информации (метаданных), относящейся к ней. Чтобы указать аннотацию, надо над заголовком класса или метода, либо надо объявлением поля или переменной, написать после @ название аннотации (класса аннотации), например так:

@Override
public void doSomeThing() {
}


Кроме того, у аннотации могут быть свойства, они указывают в скобках через запятую в виде пар «ключ=значение», где в качестве ключа выступает название свойства, а качестве значения — собственно, значение, которое должно принять это свойство. Выглядит это так:
@CatInfo(manager=Catmanager.class, unique=true)
class Cat {}
Если указывается указывает значение только для одного свойства, то имя свойства и знак равно можно не писать: @SuppressWarnings(«unchecked).
Также можно вообще не ставить скобки, если никаким свойствам не присваиваются никакие значения.
Чтобы создать свою аннотацию, надо указать модификатор доступа, потом после пробела ключевое слово „@interface“ и дальше опять после пробела имя аннотации (принять начинать его с большой буква). Дальше идёт тело аннотации в фигурных скобках. Внутри тела указываются свойства в виде объявлений методов (как в интерфейсах). Также у свойств можно указать значения по умолчанию (они их будут принимать, если при указании аннотации в нужном месте, этому свойству не будет присвоено какое-то значение). Всё вместе это выглядит так:
@interface CatManager
{
Class manager();
boolean unique();
String name() default „Unknown Cat“;
}

Аннотации выполняют следующие функции:
а) дают необходимую информацию для компилятора;
б) дают информацию различным инструментам для генерации другого кода, конфигураций и т. д.;
в) могут использоваться во время работы кода;
е) повышают читабельность кода и его понимание программистами.
На данный момент компилятором используют три аннотации: @Deprecated, @Override и @SuppressWarnings. Первой аннотацией помечаются устаревшие методы и классы, нерекомендованные к использованию (комплятор по их поводу показывает предупреждение). Вторая аннтоцая ставится над переопределёнными методами класса-наследника (это позволяет контролировать связь между исходным методом и переопределённым). Третья аннотация позволяет подавлять (не выводить) некоторые исключительные предупреждения, обычно выводимые компилятором в связи с данным методом или классом (например, что он уже устарел и нерекомендован к использованию).