• ,

Уровень 35. Ответы на вопросы к собеседованию по теме уровня.

Вопросы/дополнения/критика приветствуются.

Какие системы контроля версий вы знаете?
Git, SVN, Bazaar, Mercurial

Чем отличаются SVN и Git?
  1. GIT — распределенная СКВ, а SVN — нет. Другими словами, если есть несколько разработчиков работающих с репозиторием у каждого на локальной машине будет ПОЛНАЯ копия этого репозитория. Разумеется есть и центральная машина, с которой можно клонировать репозиторий. Это напоминает SVN. Основной плюс Git в том, что если вдруг у вас нет доступа к интернету, сохраняется возможность работать с репозиторием. Потом только один раз сделать синхронизацию и все остальные разработчики получат полную историю.
  2. GIT сохраняет метаданные изменений, а SVN целые файлы. Это экономит место и время.

Что такое GitHub? У вас есть проекты на GitHub?
GitHub — веб-сервис хостинга проектов с использованием системы контроля версий git, а также как социальная сеть для разработчиков. Пользователи могут создавать неограниченное число репозиториев, для каждого из которых предоставляется wiki, система issue tracking-а, есть возможность проводить code review и т.п. Кроме Git, сервис поддерживает получение и редактирование кода через SVN и Mercurial.

Зачем нужны системы контроля версий?
СКВ дает возможность возвращать отдельные файлы к прежнему виду, возвращать к прежнему состоянию весь проект, просматривать происходящие со временем изменения, определять, кто последним вносил изменения во внезапно переставший работать модуль, кто и когда внес в код какую-то ошибку, и т.п… Вообще, если, пользуясь СКВ, вы всё испортите или потеряете файлы, всё можно будет легко восстановить.

Что такое generic? Как они реализованы в Java?
Generics — это параметризованные типы. С их помощью можно объявлять классы, интерфейсы и методы, где тип данных указан в виде параметра. Обобщения добавили в язык безопасность типов.

Пример реализации:
class MyClass<T>{
  T obj;
  public MyClass(T obj){
    this.obj = obj;
  }
}

class MyClass<T>

В угловых скобках используется T — имя параметра типа. Это имя используется в качестве заполнителя, куда будет подставлено имя реального типа, переданного классу MyClass при создании реальных типов. То есть параметр типа T применяется в классе всякий раз, когда требуется параметр типа. Угловые скобки указывают, что параметр может быть обобщен. Сам класс при этом называется обобщенным классом или параметризованным типом.
Далее тип T используется для объявления объекта по имени obj:
T obj;

Вместо T подставится реальный тип, который будет указан при создании объекта класса MyClass. Объект obj будет объектом типа, переданного в параметре типа T. Если в параметре T передать тип String, то экземпляр obj будет иметь тип String.
Рассмотрим конструктор MyClass():
public MyClass(T obj){
  this.obj = obj;
}

Параметр obj имеет тип T. Это значит, что реальный тип параметра obj определяется типом, переданным параметром типа T при создании объекта класса MyClass.
Параметр типа T также может быть использован для указания типа возвращаемого значения метода.
В именах переменных типа принято использовать заглавные буквы. Обычно для коллекций используется буква E, буквами K и V — типы ключей и значение (Key/Value), а буквой T (и при необходимости буквы S и U) — любой тип.
Обобщения работают только с объектами. Поэтому нельзя использовать в качестве параметра элементарные типы вроде int или char.

*Так же считаю нужным упомянуть generic методы. Это методы вида:
модификаторы <T, ...> возвращаемыйТип имяМетода(T t, ...)
Как я понял, если в качестве типа в сигнатуре метода используются параметры, необходимо перед типом возвращаемого значения их перечислить. Верно ли это?

Более подробную информацию можно посмотреть по следующим ссылкам:
http://developer.alexanderklimov.ru/android/java/generic.php
http://www.quizful.net/post/java-generics-tutorial

Что такое стирание типов?
Внутри класса-дженерика не хранится информация о его типе параметре. Это и называется стиранием типов. На стадии компиляции происходит приведение объекта класса к типу. который был указан при объявлении.
Пример:


Что такое wildcard?
Wildcard — это дженерик вида <?>, что означает, что тип может быть чем угодно. Используется, например, в коллекциях, где для всех коллекций базовым типом является Сollection<?>.

Полезная ссылка:
http://www.k-press.ru/cs/2008/3/generic/generic.asp

Расскажите про extends и super в Generic'ах?
Чтобы наложить ограничение на wildcard необходимо использовать конструкции типа:
? extends SomeClass — означает, что может быть использован любой класс-наследник SomeClass
? super SomeClass — означает, что может быть использован класс SomeClass, либо класс-родитель (или интерфейс) SomeClass
Это называется bounded wildcard.
Для того, чтобы определиться с выбором между extends и super был придуман метод PECS.
Подробно про это можно прочитать по ссылке ниже:
https://habrahabr.ru/post/207360/

Как использовать wildcard?
Пример использования wildcard:
List<?> numList = new ArrayList<Integer>();

Вопрос я не понял, но в принципе использование wildcard’ов рассматривается в материалах по ссылкам выше.

В чем отличие ArrayList и ArrayList<?>
Запись вида ArrayList называется raw type (обычный тип). Она эквивалентна записи вида ArrayListи используется для обратной совместимости, т.к. до Java 1.5 не было дженерик коллекций. По возможности такой формы записи следует избегать.
ArrayList<?> является супертипом для ArrayList.

8 комментариев

lichMax
  • lichMax
  • 0
  • Комментарий отредактирован 2017-07-12 17:16:15 пользователем lichMax
Пункт «б» ответа на первый вопрос неверный. Правильный ответ такой:
«Git хранит „слепки“ файлов в сжатом виде (причём, если файл не менялся, то хранится ссылка на него), а SVN хранит изменения файлов.» Тут например есть про это. И вот ещё ссылки про сравнение этих двух СКВ: первая, вторая

Но если говорить вообще, то чёткого сравнения в интернете я и не нашёл. А некоторые статьи и высказывания, как я понял, уже устарели. Вот что у меня получилось по пунктам:
а) SVN — централизованная СКВ, а Git — распределённая СКВ. Соответственно, гит хранит все файлы и всю историю на локальном диске, SVN — же на сервере.
б) Git хранит «слепки» файлов в сжатом виде (причём, если файл не менялся, то хранится ссылка на него), а SVN хранит изменения файлов.
в) В Git коммит может иметь несколько родителей (разных веток) и несколько потомков (разных веток), а в SVN — нет. Соответственно, в SVN — линейная история коммитов, а в Git — нет.
г) В Git ветка — это просто указатель на какой-то коммит, в SVN — это полноценная копия всего репозитория. (?)
д) Git создают одну скрытую папку в корне проекта, в которой хранит всю свою служебнуюинформацию, а SVN в каждой папке проекта создаёт скрытую папку со своей служебной информацией. (?)
Последние два пункт с вопросами, потому что по ним несколько противоречивая информация (думаю, из-за разных версий SVN, которыми пользовались люди).
lichMax
Ещё можно добавить такую ссылку к пункту «б» ответа на первый вопрос: ссылка
lichMax
  • lichMax
  • 0
  • Комментарий отредактирован 2017-07-12 17:32:22 пользователем lichMax
Небольшие замечания по ответу на пятый вопрос. Там есть такое предложение: «Это имя используется в качестве заполнителя, куда будет подставлено имя реального типа, переданного классу MyClass при создании реальных типов.» Что значит «создание типов»? Вообще-то конкретный тип вместо типа-параметра подставляется при конкретном использовании класса или метода. Первое — это объявление перемменной, у которой в качестве типа выступает данный дженерик-класс, или наследование от данного обобщённого класса или интерфейса. Второе — это вызов метода.

И ещё, такое предложение: «Сам класс при этом называется обобщенным классом или параметризованным типом.» Параметрическим типом как раз явлется тип, указываемый в угловых скобках (его ещё называют типо-параметром).
lichMax
Опять-таки, ответ на вопрос про WildCard: «Wildcard — это дженерик вида <?>». Дженерик это класс, который имеет параметрический тип (записываемый в угловых скобках). А wildcard, как я понял, это разновидность типа-параметра (но не дженерик).
lichMax
Расскажите про extends и super в Generic'ах?
Дополнение: эти ключевые слова могут использовать не только вместе со знаком вопроса (в wildcard), но и с буквами (то есть в обычном параметрическом типе).
lichMax
*могут использоваться
lichMax
Как использовать wildcard?
Тоже не совсем понял вопрос. Но как я понял, здесь надо рассказать про весь синтаксис с использованием wildcard (то есть где используется такая контрукция, в каких местах в языке).
lichMax
  • lichMax
  • 0
  • Комментарий отредактирован 2017-07-12 19:14:49 пользователем lichMax
Ещё одно. Цитата из этих ответов:
В чем отличие ArrayList и ArrayList<?>
Запись вида ArrayList называется raw type (обычный тип). Она эквивалентна записи вида ArrayListи используется для обратной совместимости, т.к. до Java 1.5 не было дженерик коллекций. По возможности такой формы записи следует избегать.
ArrayList<?> является супертипом для ArrayList.
Как-то туманно написано, особенно это: «Запись вида ArrayList называется raw type (обычный тип). Она эквивалентна записи вида ArrayList». Либо опечатка, либо бездумный копипаст какой-нибудь.
Сам для себя пока нашёл одно отличие между ArrayList и ArrayList<?>: в список типа ArrayList можно вставить элемент любого типа, а в список типа ArrayList<?> — только null. А вот подстановка списков с конкретным типом переменных вместо параметров с данными типами — происходит одинаково. Кроме того, чтение данных из списков этих двух типов тоже проходит одинаково (и в обоих случаев это происходит без проблем).
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.