Вы находитесь на странице: 1из 118

Вопросы на собеседовании

1. Перечислите методы класса Object

2. Зачем нужны методы equals & hashCode?

3. Что будет, если переопределить equals, но не переопределить hashCode?

4. Зачем нужны методы wait, notify, notifyAll?

5. Как правильно клонировать объект?

6. Зачем нужен метод finalize() и как он работает?

7. В чем отличие final, finally, finalize?

8. Что такое try-with-resources?

9. Чем отличаются методы wait(1000) и sleep(1000)?

10. В чем отличие i++ и ++i ?

11. Как правильно сравнить две строки в Java?

12. Как правильно сравнить две строки в Java игнорируя регистр букв?

13. Как отсортировать список строк в алфавитном порядке?

14. В какой кодировке хранятся строки в Java?

15. Как преобразовать строку в кодировку Windows-1251?

16. Как разбить строку на отдельные слова?

17. Как развернуть строку задом наперед?

18. Что происходит, когда мы пишем "A" + "b" + "C"?

19. Что такое mutable и immutable типы?

20. Что дает типу String то, что его сделали immutable?

21. Какие бывают внутренние классы?

22. Во что компилируется анонимный внутренний класс?

23. Зачем использовать ключевое слово final при создании анонимных классов?

24. Как правильно создать объект внутреннего класса?

25. Как правильно создать объект вложенного класса?

26. Можно ли создавать статические методы/переменные во внутреннем классе?


27. Назовите три любых внутренних класса?

28. Как внутренние классы решают проблему множественного наследования в Java?

29. Чем отличаются анонимные классы, созданные на основе интерфейса и на основе


класса?

30. Можно ли создать анонимный статический вложенный класс?

31. Во что компилируются анонимные внутренние классы?

32. Можно ли наследовать внутренние классы?

33. Можно ли наследовать анонимные внутренние классы?

34. Можно ли переопределять внутренние классы?

35. Какие ограничения есть у локальных классов?

36. Может ли анонимный внутренний класс содержать статические методы?

37. Можно ли создать объект внутреннего класса, если у внешнего класса только
private конструктор?

38. Можно ли объявлять внутренние классы private?

39. Можно ли объявлять анонимные внутренние классы private?

40. Сколько у класса максимально может быть внутренних классов?

41. Что такое ThreadGroup и зачем он нужен?

42. Что такое ThreadPool и зачем он нужен?

43. Что такое ThreadPoolExecutor и зачем он нужен?

44. Что такое Concurrency?

45. Что такое «атомарные типы» в Java?

46. Зачем нужен класс ThreadLocal?

47. Что такое модификатор volatile?

48. Что такое Executor?

49. Что такое ExecutorService?

50. Зачем нужен ScheduledExecutorService?

51. Назовите все состояния объекта Thread?

52. В какие состояния может перейти нить, при входе в блок synchronized?

53. В какое состояние перейдет нить, при вызове метода wait()?


54. В какое состояние перейдет нить, при вызове метода wait(500)?

55. В какое состояние перейдет нить, при вызове метода notify()?

56. В какое состояние перейдет нить, при вызове метода notifyAll()?

57. Три нити в блоке synchronized вызвали wait() у объекта-мютекса. В какое состояние
перейдут эти нити, если четвертая нить вызовет notifyAll()?

58. Чем отличается join(500) от wait(500)?

59. Чем отличается wait(500) от sleep(500)?

60. В какое состояние перейдет нить при вызове метода yield()?

61. Какие методы есть у класса Collections?

62. Какие методы есть у класса Arrays?

63. Как называется сортировка, которая используется при вызове Collections.sort()?

64. Что такое mutex?

65. Что такое монитор?

66. Какие есть атомарные типы?

67. Что такое канкаренси? Какие классы есть в канкаренси?

68. Что такое «happens-before»?

69. Что такое «барьер» в канкаренси?

70. Как пользоваться интерфейсом Comparable?

71. Как пользоваться интерфейсом Comparator?

72. Как устроен класс ConcurrentHashMap?

73. Что такое класс Lock?

74. Что такое итератор?

75. Чем плох оператор goto?

76. Что такое зарезервированные слова в Java?

77. Что произойдет, если вызвать wait не в блоке synchronized?

78. Как скомпилировать java-файл из консоли?

79. Как запустить java-файл из консоли?

80. Как запустить программу из нескольких скомпилированных файлов из консоли?

81. Как создать директорию с поддиректориями: (doc/release/com/javarush/test)?


82. Как получить список файлов в директории по маске (шаблону) «*.doc»?

83. Назначение и методы класса BlockedQueue?

84. Что такое дедлок?

85. Какие вы знаете стратегии, предотвращающие появление дедлоков?

86. Могут ли возникнуть дедлоки при использовании методов wait-notify?

87. Что чаще используется: notify или notifyAll?

88. Метод wait рекомендуется использовать с конструкциями if или while?

89. Что происходит после вызова метода notifyAll?

90. Какие выгоды получает объект, если он immutable?

91. Что такое «thread-safe»?

92. Что такое JMM?

93. Какое исключение вылетит, если вызвать wait не в блоке synchronized?

94. Как получить список живых нитей из группы ThreadGroup?

95. Как получить список мертвых нитей из группы ThreadGroup?

96. Аналоги ThreadPoolExecutor?

97. Что такое ThreadWorker?

98. Что такое ThreadPool?

99. Что такое FactoryMethod?

100. Что такое DDD?

101. Что такое TDD?

102. Что такое dump?

103. Что такое Pool?

104. Какие приоритеты нитей бывают?

105. Можно ли остановить нить, снизив ее приоритет до 0?

106. Зачем нужен класс ThreadGroup?

107. В какой группе нитей состоит main-thread?

108. Что такое паттерн ThreadPool?

109. Зачем нужен класс ThreadPoolExecutor?


110. Сколько способов создать нить вы знаете? (Thread, Runnable, Callable<T>)

111. Для чего используется класс Future?

112. В чем преимущества Callable над Runnable?

113. Можно ли отменить выполнение задачи, если использовать класс Future?

114. Что такое autoboxing?

115. Зачем используется autoboxing?

116. Альтернативы autoboxing?

117. Типы-обертки для примитивных типов mutable или immutable?

118. Как примитивные типы приводятся к непримитивным аналогам?

119. Как непримитивные типы приводятся к примитивным?

120. Как сравниваются примитивные и непримитивные типы?

121. Всегда ли создается новый объект при операции autoboxing?

122. Как работает кэширование при операции autoboxing?

123. Для каких типов и/или значений работает кэширование?

124. Как преобразовать число из одной системы счисления в другую?

125. Что такое base64?

126. Что произойдет, если поместить оператор return или System.exit () в блок
try/catch/finally?

127. Поддерживает ли язык Java множественное наследование?

128. В случае, когда метод генерирует исключение NullPointerException в


родительском классе, можно ли его переопределить методом, генерирующим
RuntimeException?

129. Как гарантировать возможность обращения N нитей к N ресурсам без взаимной


блокировки?

130. В чем разница между классами StringBuffer и StringBuilder в языке Java?

131. Что вернет выражение 1.0/0.0? Приведет ли оно к генерации исключения или
ошибке при компиляции?

132. Что будет, если попытаться вставить в HashMap уже имеющийся в ней ключевой
объект?

133. Что такое NaN?

134. Как получить бесконечность в Java?


135. Как проверить, что в результате вычисления получилась бесконечность?

136. Что такое битовая маска?

137. Где применяют битовые маски?

138. Как установить бит в единицу в битовой маске?

139. Как установить бит в ноль в битовой маске?

140. Как получить значение определенного бита в битовой маске?

141. Что такое ленивое вычисление выражения?

142. Чем отличается использование && и & для типа boolean?

143. Как получить список всех файлов в директории и ее поддиректориях?

144. Как получить список всех файлов в директории с расширением zip?

145. Как заархивировать файл?

146. Как заархивировать много файлов?

147. Как заархивировать много файлов и директорий?

148. Как разархивировать файл?

149. Как задать кодировку файла?

150. Как узнать кодировку файла в архиве?

151. Как поменять данные (свойства) в объекте типа Properties?

152. Может ли объект File соответствовать файлу, которого еще нет?

153. Как преобразовать объект File к типу Path?

154. Зачем нужен класс Files?

155. Какие классы для архивации вы знаете?

156. Как добавить директорию в архив?

157. Зачем нужны Properties?

158. В каком виде хранятся данные в файле .properties?

159. Можно ли изменять данные в объекте Properties после загрузки их из файла?

160. Зачем нужен класс FileReader?

161. Зачем нужен класс FileWriter?

162. Как записать информацию в файл в произвольном месте?


163. Как прочитать 10000-ю строку из файла, не читая предыдущих?

164. Как преобразовать строку в Reader?

165. Как преобразовать Writer в строку?

166. Как создать прокси-объект?

167. Как написать RMI клиент?

168. Как написать RMI сервер?

169. Как разрешитьRMI-доступ из других компьютеров сети?

170. Распространённые RMI ошибки?

171. Зачем нужен RandomAccessFile?

172. Что будет если файл, откуда читает RandomAccessFile, не существует?

173. Что будет если файл, куда пишет RandomAccessFile, не существует?

174. Зачем нужен класс StringReader?

175. Зачем нужен класс StringWriter?

176. Зачем нужен класс ByteArrayStream?

177. Зачем нужен класс PrintStream? Назовите места, где он используется?

178. Зачем нужен DynamicProxy?

179. Как работает RMI?

180. Объекты каких типов можно передавать по RMI?

181. Что такое JSON?

182. В чем связь JSON и JavaScript?

183. Как использовать Jackson?

184. Java jackson. Как настроить сериализацию в JSON?

185. Настройка JAXB?

186. Сериализация в JAXB примеры?

187. Аннотации в JAXB?

188. Документация по Jackson?

189. Документация по JAXB?

190. Проблемы десериализации в Jackson?


191. В чем отличия Java и JavaScript?

192. В чем отличия JSON и XML?

193. Какие фреймворки для работы с JSON вы знаете?

194. Какие фреймворки для работы с XML вы знаете?

195. Какие аннотации Jackson вы знаете?

196. Какие аннотации JAXB вы знаете?

197. В чем отличие сериализации и десериализации в JSON?

198. Что лучше JSON или XML? Почему?

199. Что такое DTO?

200. Как работает сборщик мусора в Java?

201. Какие бывают виды сборщиков мусора?

202. Что такое «поколения» объектов?

203. Для чего используется SoftReference?

204. Пример использования SoftReference?

205. Пример использования WeakReference?

206. Зачем нужен WeakHashMap?

207. Что такое логгер?

208. Как настроить логгер?

209. Когда вызывается метод finalize?

210. Что произойдет, если в методе finalize возникнет исключение?

211. Что такое PhantomReference?

212. Зачем нужно передавать очередь в конструктор PhantomReference?

213. Какие системы контроля версий вы знаете?

214. Чем отличаются SVN и Git?

215. Что такое GitHub? У вас есть проекты на GitHub?

216. Зачем нужны системы контроля версий?

217. Что такое generic? Как они реализованы в Java?

218. Что такое стирание типов?


219. Расскажите про extends и super в Generic’ах?

220. Что такое wildcard?

221. Как использовать wildcard?

222. В чем отличие ArrayList и ArrayList<?>

223. Что такое граф?

224. Что такое дерево из теории графов?

225. Что такое бинарное дерево?

226. Что такое красно-черное дерево?

227. Что такое MVC?

228. Что такое EJB?

229. Что такое DAO и DTO?

230. Устаревшие коллекции в java?

231. Чем отличается TreeMap и HashMap?

232. Чем отличается TreeSet и HashSet?

233. Что такое POJO?

234. Что такое Entity?

235. Какие коллекции-списки вы знаете?

236. Какие коллекции-множества вы знаете?

237. Что такое map, чем он отличается от «словаря»?

238. Что такое Queue и Dequeue?

239. Какие классы, реализующие интерфейс Queue вы знаете?

240. Что такое дерево?

241. Что такое паттерны проектирования?

242. Какие паттерны проектирования вы знаете?

243. Расскажите про паттерн Singleton? Как сделать его потокобезопасным?

244. Расскажите про паттерн Factory

245. Расскажите про паттерн AbstractFactory

246. Расскажите про паттерн Adaper, его отличия от Wrapper?


247. Расскажите про паттерн Proxy

248. Что такое итератор? Какие интерфейсы, связанные с итератором, вы знаете?

249. Зачем нужен класс Arrays?

250. Зачем нужен класс Collections?

251. Что такое Agile?

252. Что такое Scrum?

253. Какие роли Scrum вы знаете?

254. Что такое спринт? Расскажите с подробностями

255. Кто такие QA?

256. Кто такой product owner?

257. Расскажите об иерархии исключений

258. Что делать если JVM выкинула Error?

259. Какие нововведения в области исключений из Java 7 вы знаете?

260. Зачем нужны аннотации? Как ими пользоваться?

261. Что такое web-сервер?

262. Что такое Tomcat?

263. Что такое сервлеты и где они используются?

264. Какие режимы запуска приложений в IDEA вы знаете?

265. Можно ли дебажить приложение/сервлет, которое запущено внутри Tomcat’а?

266. Как в IDEA установить точку остановки?

267. Как в IDEA посмотреть список всех точек остановки?

268. Можно ли с помощью IDEA поменять значение переменной в процессе работы


программы?

269. Как в IDEA настроить отступы?

270. Как в IDEA настроить, чтобы { отображалось на той же строке, а не на новой?

271. Что такое IP-адрес?

272. В чем отличие host и domain?

273. Какие методы в HTTP вы знаете?

274. Чем отличаются методы GET, POST и HEAD?


275. Что такое REST?

276. Зачем нужен класс Calendar в Java?

277. Как преобразовать дату в Java к нужному формату?

278. В чем отличие URI и URL?

279. Что такое сокеты?

280. Отличие классов Socket и URL?

Ответы.

1.Перечислите методы класса Object.

boolean equals(Object)

int hashcode()

String toString()

Object clone()

Class getClass()

void finalize()

void wait(), wait(long timeout), wait(long timeout, int nanos)

void notify()

notifyAll()

2. Зачем нужны методы equals & hashCode?

Метод equals() используется для глубокого сравнения двух объектов, которое обычно
включает в себя сравнение всех полей между собой. Метод hashcode() используется
для быстрого сравнения двух объектов, потому что сравнить два целых числа проще,
чем все поля, некоторые из которых тоже могут быть объектами. Чаще всего
сравнение по хэшкодам используется в коллекциях для ускорения нахождения
необходимого элемента. Сначала объект ищется по хэшкоду, а потом, если объектов с
таким хэшкодом несколько, с помощью метода equals(). Объекты, которые
различаются между собой хоть немного, должны выдавать false при сравнении друг с
другом с помощью equals(). Все объекты, которые имеют одинаковые поля, должны
выдавать true при сравнении их хэшкодов.

3. Что будет, если переопределить equals, но не переопределить hashCode?


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

4. Зачем нужны методы wait, notify, notifyAll?

Данные методы используются для работы с многопоточностью и вызываются только


из синхронизированного блока или метода.

void notify() - возобновляет выполнение одного ожидающего потока.

void notifyAll() - возобновляет выполнение всех ожидающих этот объект потоков.

void wait() - освобождает монитор и переводит вызывающий поток в состояние


ожидания до тех пор, пока другой поток не вызовет метод notify().

void wait(long) - ожидание длится указанное количество миллисекунд или до получения


уведомления.

void wait(long, int) - ожидание длится указанное количество миллисекунд и наносекунд.

5. Как правильно клонировать объект?

Необходимо в классе, к которому принадлежит объект, реализовать интерфейс


Cloneable и переопределить метод clone(). В методе желательно произвести глубокое
копирование - то есть скопировать не ссылки на объекты, а сами объекты.

6. Зачем нужен метод finalize() и как он работает?

Метод finalize() предназначен для автоматического освобождения системных


ресурсов, занимаемых объектом, на котором данный метод будет вызван. Основная
цель этого метода – освободить используемые внешние не-Java ресурсы: закрыть
файлы, потоки ввода-вывода и т.п. Когда сборщик мусора (GC) добирается до
ненужного объекта, то перед его удалением он должен вызвать метод finalize(),
который, в свою очередь, должен быть переопределен в удаляемом объекте.

Недостатки:

- нет гарантии, что он будет вызван, т.к. где-то может остаться ссылка на объект.

- нет гарантии на то, в какое время будет вызван метод, так как он не вызывается
сразу, а помещается в очередь, которая обрабатывается специально созданным для
этого потоком. В очередь на финализацию попадают только те объекты, в которых
переопределен метод finalize.

- есть вероятность, что этот метод не будет вызван совсем. Это может произойти в
момент, когда объект уже станет доступным для сборщика мусора и программа
завершит свою работу.
Для освобождения ресурсов рекомендуется использовать конструкции try - catch -
finally или try-with-resourses.

7. В чем отличие final, finally, finalize?

final - модификатор доступа, который устанавливает, что переменной может быть


присвоено значение (или ссылка на объект) только один раз.

finally - ключевое слово, использующееся в конструкции try-catch-finally, и включает в


себя код, который должен выполниться в любом случае: возникло исключение или нет.
Обычно в теле finally закрываются ресурсы. Начиная с Java 7 вместо finally можно
использовать try-with-resourses.

finalize() - метод, предназначенный для автоматического освобождения системных


ресурсов, занимаемых объектом, на котором данный метод будет вызван.

8. Что такое try-with-resources?

Это специальная конструкция, появившаяся в Java 7, позволяющая открывать ресурсы


в скобках после ключевого слова try. Ресурсы закрываются автоматически после
выхода из блока try.

9. Чем отличаются методы wait(1000) и sleep(1000)?

Метод sleep (long millis) является статическим методом класса Thread, метод wait(long
timeoutMillis) является методом класса Object и может быть вызван для любого
объекта, но только в блоке synchronized. В случае с wait(1000) нить может проснутся
раньше, если получит уведомление об освобождении ресурса, вызванное с помощью
notify() или notifyAll(). Также wait() освобождает те ресурсы, с которыми работала нить.

10. В чем отличие i++ и ++i ?

В первом случае (i++) инкрементирование произойдет после того, как значение i будет
использовано в каком-либо выражении. Во втором случае (++i) переменная сначала
инкрементируется, а потом ее значение используется в выражении.

11. Как правильно сравнить две строки в Java?.

С помощью метода equals(). В классе String данный метод переопределен так, что
сравнивает не ссылки, а последовательность символов в строках.

boolean equals (Object o)

String s = "cat";

boolean test1 = s.equals("cat");//true


boolean test2 = s.equals("Cat");//false

boolean test3 = s.equals("c"+"a"+"t");//true

12. Как правильно сравнить две строки в Java игнорируя регистр букв?

Метод equalsIgnoreCase – совпадают ли строки, игнорируя регистр букв.

boolean equalsIgnoreCase (String str)

String s = "cat";

boolean test1 = s.equalsIgnoreCase("cat");//true

boolean test2 = s.equalsIgnoreCase("Cat");//true

boolean test3 = s.equalsIgnoreCase("cAT");//true

13. Как отсортировать список строк в алфавитном порядке?

Используя метод Collections.sort().

ArrayList list = new ArrayList<>();

list.add("zas");

list.add("fas");

list.add("sd");

list.add("asdg");

Collections.sort(list);

14. В какой кодировке хранятся строки в Java?

В кодировке UTF-16

15. Как преобразовать строку в кодировку Windows-1251?

С помощью конструктора класса String(byte[] bytes, String charsetName)

String utf8 = "text";

byte[] bytes1251 = utf8.getBytes("windows-1251"); //перевод строки в байты в w-1251

String win1251 = new String(bytes1251,"windows-1251"); //перевод байт в строку


16. Как разбить строку на отдельные слова?

С помощью метода String[] split(String regex)

или класса StringTokenizer:

String s = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(s,"ne");

while (tokenizer.hasMoreTokens())

{String token = tokenizer.nextToken();

System.out.println(token);}

17. Как развернуть строку задом наперед?

С помощью методов StringBuffer reverse() или StringBuilder reverse()

StringBuffer s = new StringBuffer("text");

StringBuilder s1 = new StringBuilder("TexT");

String s2 = s.reverse().toString(); //txet

String s3 = s1.reverse().toString(); //TxeT

18. Что происходит, когда мы пишем "A" + "b" + "C"?

Происходит сложение (конкатенация) строк.

new StringBuilder().append("A").append("b").append("C").toString();

19. Что такое mutable и immutable типы?

Объекты, которые после их создания изменить нельзя, называются неизменяемыми


или immutable.

Объекты, которые после создания можно изменить, называются изменяемыми или


mutable.

Неизменяемые объекты можно реализовать значительно проще, чем изменяемые и


использовать одновременно из разных нитей.

20. Что дает типу String то, что его сделали immutable?
-String широко используется, как параметр для многих классов Java, в частности для
открытия сетевых соединений, подключений к БД, открытию файлов и пр. И если бы
строка изменялась, то мы могли получить доступ к объекту (файлу например), на
который мы имеем право, затем изменить строку с именем (случайно или намеренно)
и получить доступ уже к другому файлу.Так же String используется в механизме
загрузки файлов, и это – фундаментальный аспект. И если бы строка изменялась, то
запрос на загрузку "java.io.Writer" мог бы быть изменён на "DiskErasingWriter".

- Из-за того, что строка не изменяется, она кэширует свой хэшкод и не вычисляет его
каждый раз, когда мы его вызываем, что делает строку очень быстрой как ключ для
hashmap.

- immutable делает экземпляры строк потокобезопасными

21. Какие бывают внутренние классы?

Внутренние классы, как разновидность вложенных классов (нестатических), бывают 3


типов:

- Просто внутренние классы

- Локальные

- Анонимные

22. Во что компилируется анонимный внутренний класс?

Анонимный внутренний класс компилируется в обычный внутренний класс


(безымянный внутренний нестатический класс, реализующий существующий класс или
интерфейс, и один уникальный объект данного класса).

23. Зачем использовать ключевое слово final при создании анонимных классов?

Ключевое слово final должно применяться ко всем локальным переменным,


объявленных вне анонимного класса, и которые будут использоваться им. Локальные
переменные должны быть финальными для того, что бы пользователь класса был
уверен в том, что пока он работает с данными они не изменятся во внешнем коде, что
их состояние остаётся актуальным на всём протяжении жизни анонимного класса.
Если не объявить такие переменные final, то компилятор сообщит об ошибке.

24. Как правильно создать объект внутреннего класса?

Внутренние (не статические) классы, как переменные и методы связаны с объектом


внешнего класса. Внутренние классы так же имеют прямой доступ к полям внешнего
класса. Такие классы не могут содержать в себе статические методы и поля.
Внутренние классы не могут существовать без экземпляра внешнего. Для создания
объекта:
OuterClass outer = new OuterClass();

InnerClass inner = outer.new InnerClass();

25. Как правильно создать объект вложенного класса?

Синтаксис создания объекта вложенного класса:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

26. Можно ли создавать статические методы/переменные во внутреннем классе?

Внутренний класс не может содержать статические переменные и методы. Внутренние


(не статические) классы, как переменные и методы, связаны с объектом внешнего
класса. Такие классы не могут содержать в себе статические методы и поля.

27. Назовите три любых внутренних класса?

1. private static class Holder — вложенный класс HashMap из java.util.

2. В интерфейсе Map есть interface Entry<K,V>, который опять же в HashMap и


реализуется в другом вложенном классе static class Entry<K,V> implements
Map.Entry<K,V>.

3. private static class IntegerCache в классе Integer.

28. Как внутренние классы решают проблему множественного наследования в Java?

Ещё одним плюсом внутренних классов является частичное решение проблемы


множественного наследования, которое запрещено в java. Если классу А необходимо
использовать protected методы класса B и C, то можно от класса В унаследоваться, а
внутри себя объявить класс D, который будет наследником С. Таким образом у класса
А появится доступ к желаемым методам нескольких классов.

29. Чем отличаются анонимные классы, созданные на основе интерфейса и на основе


класса?

Анонимный класс, созданный на основе интерфейса, требует переопределения всех


его методов. Анонимный класс на основе класса не предъявляет таких требований.

Если в программе используется анонимный класс на основе интерфейса с одним


методом, то его можно заменить лямбда выражением. С анонимным классом на
основе другого класса такого варианта не предоставляется по естественным
причинам.
30. Можно ли создать анонимный статический вложенный класс?

Анонимный класс является статическим в зависимости от того находится ли он в


статическом блоке кода или нет.

31. Во что компилируются анонимные внутренние классы?

Анонимные внутренние классы компилируются в файлы внешнийКласс$n.class. На


месте внешнего класса, соответственно, название обрамляющего класса, внутри
которого описывается анонимный внутренний класс. На месте n число от 1 до
количества анонимных классов.

32. Можно ли наследовать внутренние классы?

Да.

33. Можно ли наследовать анонимные внутренние классы?

Описывая анонимный класс мы уже наследуемся от какого-то класса или реализуем


какой-либо интерфейс. К анонимным классам напрямую нельзя применить слова
extends или implements, но ведь никто не мешает заранее подготовиться и расширить
нужный интерфейс, который будем реализовывать с помощью анонимного класса.
Пример в коде ниже

public class TestExtendAnonym {

private interface MyInterface extends Runnable, WindowListener {

Runnable r = new MyInterface() {

...

//Пример того как реализовать 2 и более интерфейса в анонимном классе

};

34. Можно ли переопределять внутренние классы?

1)Есть некий класс A, внутри которого некий класс B;


2) Мы хотим создать класс C, наследующийся от класса А и ещё раз описать в классе
С класс В.

Повторное описание внутреннего класса — это не более чем работа с пространством


имён. Итог — внутренний класс, подобно методам, переопределить нельзя.

35. Какие ограничения есть у локальных классов?

Локальный класс наделён особенностями внутренних классов, но имеет


отличительные черты, а именно:

1)он имеет доступ только к финальным полям и аргументам обрамляющего метода, а


также ко всем полям обрамляющего класса, в том числе приватным и статическим;

2)локальный класс виден и может создаваться только в блоке, в котором описан;

3)у локального класса не ставится модификатор доступа;

4)не может иметь статических полей, методов, классов (за исключением финальных);

5)локальный класс, объявленный в статическом блоке, может обращаться только к


статическим полям внешнего класса.

36. Может ли анонимный внутренний класс содержать статические методы?

Нет. У анонимных внутренних классов, как и у внутренних классов не может быть


статических полей, методов

37. Можно ли создать объект внутреннего класса, если у внешнего класса только
private конструктор?

Напрямую создать объект вне обрамляющего класса не получится. Но можно создать


метод, возвращающий экземпляр класса. Либо через рефлексию.

38. Можно ли объявлять внутренние классы private?

Можно. Если мы объявим внутренний класс как private, доступ к созданию объектов у
нас будет только внутри обрамляющего класса.

39. Можно ли объявлять анонимные внутренние классы private?

Да.

40. Сколько у класса максимально может быть внутренних классов?


Сколько угодно, в зависимости от особенностей ОС.

41. Что такое ThreadGroup и зачем он нужен?

Класс ThreadGroup представляет собой набор нитей, которые могут содержать в себе
другие группы нитей. Группа нитей образует дерево, в котором каждая другая группа
нитей имеет родителя (кроме исходной). Поток имеет право доступа к данным из
своей группы нитей, но не имеет такого доступа к другим группам или к родительской
группе потоков.

Также данный класс реализует интерфейс Thread.UncaughtExceptionHandler.

42. Что такое ThreadPool и зачем он нужен?

Пул потоков (нитей) представляет собой управляемую коллекцию потоков, которые


доступны для выполнения различных задач. Пулы нитей, как правило, обеспечивают:

-Повышение производительности при выполнении большого количества задач в связи


с сокращением накладных расходов на вызов каждой задачи.

-Является средством ограничивающим расход ресурсов при выполнении набора


задач.

-Избавляют от необходимости управления жизненным циклом нитей.

43. Что такое ThreadPoolExecutor и зачем он нужен?

ThreadPoolExecutor – реализация интерфейса ExecutorService. Он выполняет


переданную задачу (Callable или Runnable), используя одну из внутренних доступных
нитей из пула. Пул потоков содержит в себе ThreadPoolExecutor, который может
содержать изменяющееся число нитей. Число нитей в пуле задается с помощью
corePoolSize и maximumPoolSize.

44. Что такое Concurrency?

Конкурентность — это свойство систем (программы, сети, компьютера и т.д.),


допускающее одновременное выполнение нескольких вычислительных процессов,
которые могут взаимодействовать друг с другом. В современных языках
программирования принцип конкурентности обычно реализован в виде процесса
многопоточности. Многопоточность позволяет программе работать в нескольких
потоках, предоставляя преимущества параллелизации (быстрое исполнение,
эффективное использование ресурсов и т.д.), но она также сохраняет и её недостатки
(о них ниже), поэтому некоторые языки используют механизм, названный Global
Interpreter Lock (он предотвращает одновременное исполнение более чем одного
потока — даже на многоядерных процессорах).
45. Что такое «атомарные типы» в Java?

http://java-online.ru/concurrent-atomic.xhtml

Операция называется атомарной тогда, когда её можно безопасно выполнять при


параллельных вычислениях в нескольких потоках, не используя при этом ни
блокировок, ни synchronized. Например, при работе в многопоточной среде операции
инкремента и декремента могут стать источником ошибок. Т.е. в многопоточной среде
простые с виду операции инкремента и декремента требуют использование
синхронизации и блокировки.

Блокировка подразумевает пессимистический подход, разрешая только одному потоку


выполнять определенный код, связанный с изменением значения некоторой «общей»
переменной. Таким образом, никакой другой поток не имеет доступа к определенным
переменным. Но можно использовать и оптимистический подход. В этом случае
блокировки не происходит, и если поток обнаруживает, что значение переменной
изменилось другим потоком, то он повторяет операцию снова, но уже с новым
значением переменной. Так работают атомарные классы.

Атомарные классы пакета java.util.concurrent.atomic можно разделить на 4 группы:

1) Atomic-классы для boolean, integer, long и ссылок на объекты: AtomicBoolean,


AtomicInteger, AtomicLong, AtomicReference;

2) Atomic-классы для массивов integer, long и ссылок на объекты: AtomicIntegerArray,


AtomicLongArray, AtomicReferenceArray (Элементы массивов могут быть изменены
атомарно);

3) Atomic-классы для обновления полей по их именам с использованием reflection:


AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater.

4) Atomic-классы для реализации некоторых алгоритмов: AtomicStampedReference,


AtomicMarkableReference.

46. Зачем нужен класс ThreadLocal?

Класс java.lang.ThreadLocal<T> используется для хранения переменных, которые


должны быть доступны для всего потока. ThreadLocal переменные отличаются от
обычных переменных тем, что у каждого потока свой собственный, индивидуально
инициализируемый экземпляр переменной, доступ к которой он получает через
методы get() или set(). У каждого потока – т.е. экземпляра класса Thread – есть
ассоциированная с ним таблица ThreadLocal-переменных. Ключами таблицы являются
cсылки на объекты класса ThreadLocal, а значениями – ссылки на объекты,
“захваченные” ThreadLocal-переменными.

47. Что такое модификатор volatile?

Ключевое слово volatile (изменчивый, не постоянный) необходимо использовать для


переменных, которые используются разными потоками. Это связано с тем, что
значение переменной, объявленной без volatile, может кэшироваться отдельно для
каждого потока, и значение из этого кэша может различаться для каждого из них.
Объявление переменной с ключевым словом volatile отключает для неё такое
кэширование и все запросы к переменной будут направляться непосредственно в
память.

private volatile boolean isCancel = false;

48. Что такое Executor?

Интерфейс java.util.concurrent.Executor используется для явного создания нитей и


предоставляет один метод - void execute(), который является заменой обычного
создания потока.

Вместо Thread(new(RunnableTask())).start() лучше использовать

Executor executor = anExecutor;

executor.execute(new RunnableTask1());

executor.execute(new RunnableTask2());

......

49. Что такое ExecutorService?

Интерфейс java.util.concurrent.ExecutorService расширяет интерфейс Executor,


добавляя множество новых методов. Основной метод — метод submit, который
принимает как Runnable, так и интерфейс java.util.concurrent.Callable<V> с
единственным методом V call() , который позволяет заданиям возвращать значение.
Метод submit возвращает интерфейс java.util.concurrent.Future, который используется
для получения результата и контролирования состояния потока.

Создание инстанса ExecutorService’а делается либо вручную через конкретные


имплементации (ScheduledThreadPoolExecutor или ThreadPoolExecutor), но проще
будет использовать фабрики класса Executors. Например, если надо создать пул с 2мя
потоками, то делается это так:

ExecutorService service = Executors.newFixedThreadPool(2);

ExecutorService service = Executors.newFixedThreadPool(2);

Если требуется создать новые потоки по мере надобности или повторно использовать
предыдущие потоки, если они свободны.

ExecutorService service = Executors.newCachedThreadPool();

ExecutorService service = Executors.newCachedThreadPool();


Если требуется запустить код несколько раз, то это будет выполняться так:

ExecutorService service = Executors.newCachedThreadPool();

for(int i = 0; i < 10; i++) {

service.submit(new Runnable() {

public void run() {

// snip... piece of code

});

Метод submit также возвращает объект Future, который содержит информацию о


статусе исполнения переданного Runnable или Callable (который может возвращать
значение). Из него можно узнать выполнился ли переданный код успешно, или он еще
выполняется. Вызов метода get на объекте Future возвратит значение, который
возвращает Callable (или null, если используется Runnable). Метод имеет 2 checked-
исключения: InterruptedException, который бросается, когда выполнение прервано
через метод interrupt(), или ExecutionException если код в Runnable или Callable бросил
RuntimeException, что решает проблему поддержки исключений между потоками.

50. Зачем нужен ScheduledExecutorService?

Интерфейс java.util.concurrent.ScheduledExecutorService расширяет интерфейс


java.util.concurrent.ExecutorService и добавляет методы schedule, которые позволяют
запланировать выполнение задания.

51. Назовите все состояния объекта Thread?

NEW, RUNNABLE(READY-RUNNING), TIME WAITING, WAITING, BLOCKED,


TERMINATED

52. В какие состояния может перейти нить, при входе в блок synchronized?

В RUNNABLE, если блок кода, помеченный synchronized, не занят другой нитью. Иначе
- в BLOCKED, после чего будет ждать освобождения объекта-мютекса.

53. В какое состояние перейдет нить, при вызове метода wait()?


WAITING

Метод wait является методом класса Object. Его можно вызвать только внутри блока
synchronized у объекта-мютекса, который был заблокирован текущей нитью, в
противном случае метод выкинет исключение IllegalMonitorStateException. В
результате вызова этого метода, блокировка с объекта-мютекса снимается, и он
становится доступен для захвата и блокировки другой нитью. При этом нить переходит
в состояние WAITING для метода wait() без параметров, но в состояние
TIMED_WAITING для метода wait(timeout).

Object monitor = getMonitor(); При вызове метода wait(), текущая нить


снимает блокировку с объекта monitor, и
synchronized(monitor) переходит в состояние WAITING, ожидая
вызова метода monitor.notify() или
{ monitor.notifyAll() другой нитью. Как только это
произойдет, нить проснется и если монитор не
… был занят, то захватит его и продолжит
работу.Если монитор окажется занят другой
monitor.wait(500); нитью, текущая нить перейдет в состояние
BLOCKED.

54. В какое состояние перейдет нить, при вызове метода wait(500)?

TIMED_WAITING

По аналогии с методом wait(), wait(timeout) можно вызвать только внутри блока


synchronized у монитора объекта, который был заблокирован текущей нитью. При
вызове метода wait(), текущая нить снимает блокировку с монитора объекта и
засыпает на 500 миллисекунд. Монитор объекта может быть захвачен другой нитью.
Через 500 миллисекунд нить проснется и, если монитор объекта не был занят, то
захватит его и продолжит работу. Если монитор окажется занят другой нитью, текущая
нить перейдет в состояние BLOCKED.

55. В какое состояние перейдет нить, при вызове метода notify()?

Метод notify() переведет нить из состояния WAITING в состояние RUNNABLE, если


монитор объекта не будет захвачен другой нитью, иначе в состояние BLOCKED
(продолжает работу потока, у которого ранее был вызван метод wait()).

56. В какое состояние перейдет нить, при вызове метода notifyAll()?


notifyAll()возобновляет работу всех нитей, у которых ранее был вызван метод wait().
Одна из всех "спящих" (WAITING) нитей перейдет в состояние RUNNABLE, захватит
монитор используемого объекта и продолжит свою работу. Остальные окажутся в
состоянии BLOCKED. Как только первая "проснувшаяся" нить отпустит монитор,
который все остальные ожидают, её участь повторит следующая нить (произвольная
нить из состояния BLOCKED перейдет в состояние RUNNABLE). Это будет
продолжаться до тех пор, пока все "пробужденные" нити не покинут состояния
BLOCKED.

57. Три нити в блоке synchronized вызвали wait() у объекта-мютекса. В какое состояние
перейдут эти нити, если четвертая нить вызовет notifyAll()?

Две из них перейдут в состояние BLOCKED, одна в состояние RUNNABLE.

58. Чем отличается join(500) от wait(500)?

Несмотря на то, что и join(500) и wait(500) переведут текущую нить в состояние


TIMED_WAITING, между ними существенные различия: join(500) вызывается у нити,
wait(500) вызывается внутри синхронизированного блока у объекта, по которому
данный блок синхронизирован.

При вызове join(500) текущая нить будет ожидать 500 миллисекунд завершения нити,
чей метод join() был вызван. Текущая нить может освободиться и раньше, если другая
нить закончит свое выполнение.

При вызове wait(500) текущая нить снимает блокировку с синхронизированного


объекта, и засыпает на 500 миллисекунд. Нить может освободиться раньше, если
прилетит notify.

Через 500 миллисекунд в обоих случаях нити продолжат работу.

59. Чем отличается wait(500) от sleep(500)?

Метод wait(500) можно вызвать в синхронизированном блоке кода с целью поставить


нить на паузу на 500мс, или же пока другая нить не пробудит уснувшую методом notify
или notifyAll. Главное в том что wait после вызова освобождает мютекс захваченного
монитора и другая нить может выполнять освобождённый блок кода.

Метод sleep(500) отправляет нить в сон на 500мс, пока не произойдёт исключительной


ситуации. «Легальных» способов вырвать нить из sleep не предусмотрено. Вызванный
в синхронизированном блоке метод sleep не обеспечивает освобождение мютекса.

60. В какое состояние перейдет нить при вызове метода yield()?


Текущая нить из состояния running переходит в состояние ready и сообщает
планировщику потоков, что готова отдать время другой нити. Планировщик же сам
решит, передать его другой нити или нет.

61. Какие методы есть у класса Collections?

Collections.sort(List myList) Сортирует список в естественном порядке.

Collections.sort(List, Comparator c) Сортировка с использованием компаратора.

Collections.shuffle(List myList) Перемешивает коллекцию в случайном порядке.

Collections.reverse(List myList) Переворачивает коллекцию в обратном порядке.

Collections.binarySearch(List mlist, T key) поиск в коллекции по ключу с


использованием бинарного поиска.

Collections.copy(List dest, List src) Копирует коллекцию источник src в dest.

Collections.frequency(Collection c, Object o) Возвращает число вхождений объекта


в коллекции.

Collections.synchronizedCollection(Collection c) Возвращает синхронизированную


(потокобезопасную) коллекцию.

62. Какие методы есть у класса Arrays?

asList(T... a)

int hashCode(type[] a)

binarySearch(type[] a, byte key)

compare(type[] a, type [] b)

copyOf(T[] original, int newLength)

equals( type[] a, type[] a2)

fill( type[] a, type val)

hashCode( type[] a)

sort( type[] a)

toString( type[] a)

...................
63. Как называется сортировка, которая используется при вызове Collections.sort()?

Сортировка слиянием.

Natural ordering — естественная сортировка

По возрастанию (ascending order)

64. Что такое mutex?

Мьютекс — это специальный объект для синхронизации потоков. У всех объектов


всех классов есть мьютекс. Задача мьютекса — обеспечить такой механизм, чтобы
доступ к объекту в определенное время был только у одного потока. Попытки других
потоков получить доступ к занятым ресурсам будут неудачными. У мьютекса есть
несколько важных особенностей. Во-первых, возможны только два состояния —
«свободен» и «занят». Во-вторых, состояниями нельзя управлять напрямую. В Java
нет механизмов, которые позволили бы явно взять объект, получить его мьютекс и
присвоить ему нужный статус. Прямой доступ к нему есть только у Java-машины.

65. Что такое монитор?

Монитор — это дополнительная «надстройка» (программный код) над мьютексом,


создающая защитный механизм при захвате потоком мьютекса объекта, так, что
другой поток не может получить доступ к синхронизированному методу. По сути,
монитор в Java выражен с помощью слова synchronized.

66. Какие есть атомарные типы?

Операция называется атомарной, если её можно безопасно выполнять при


параллельных вычислениях в нескольких потоках, не используя при этом ни
блокировок, ни синхронизацию synchronized.

Атомарные классы пакета java.util.concurrent.atomic можно разделить на 4 группы:

1) Atomic-классы для boolean, integer, long и ссылок на объекты: AtomicBoolean,


AtomicInteger, AtomicLong, AtomicReference;

2) Atomic-классы для массивов integer, long и ссылок на объекты: AtomicIntegerArray,


AtomicLongArray, AtomicReferenceArray (Элементы массивов могут быть изменены
атомарно);

3) Atomic-классы для обновления полей по их именам с использованием reflection:


AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater.

4) Atomic-классы для реализации некоторых алгоритмов: AtomicStampedReference,


AtomicMarkableReference.

67. Что такое канкаренси? Какие классы есть в канкаренси?


http://java-online.ru/concurrent.xhtml

https://habr.com/ru/post/277669/

https://habr.com/ru/company/luxoft/blog/157273/

Concurrency – это библиотека классов в Java, в которой собраны специальные классы,


оптимизированные для работы с многопоточностью.

Классы и интерфейсы пакета java.util.concurrent объединены в несколько групп по


функциональному признаку :

-collections Набор более эффективно работающих в многопоточной среде коллекций


нежели стандартные универсальные коллекции из
java.util пакета

-synchronizers Объекты синхронизации, позволяющие разработчику управлять


и/или ограничивать работу нескольких потоков.

-atomic Набор атомарных классов, позволяющих использовать


принцип действия механизма оптимистической
блокировки для выполнения атомарных операций.

-Queues Объекты создания блокирующих и неблокирующих очередей с


поддержкой многопоточности

-Locks Механизмы синхронизации потоков, альтернативы


базовым synchronized, wait, notify, notifyAll

-Executors Механизмы создания пулов потоков и планирования работы асинхронных


задач

Class ConcurrentHashMap<K,V>

Class Semaphore

Class CopyOnWriteArrayList<E>

public class CyclicBarrier

Class ReentrantLock

68. Что такое «happens-before»?

Термин, введенный Лесли Лэмпортом, означающий отношение между атомарными


командами: одно выполняется прежде другого для таких операций, и вторая команда
будет в курсе изменений, проведённых первой. Например, синхронизация и мониторы,
запись в volatile-переменную и последующее ее считывание , запуск потока и любой
код в потоке.

Эффективность исполнения программ повышается за счет того, что процессор может


выполнять операции НЕ В ТОЙ ПОСЛЕДОВАТЕЛЬНОСТИ, которую указал
программист. Мы уже все хорошо знаем, что при наличии двух и более нитей не
гарантируется последовательность выполнения из-за недетерминированного
выделения процессорного времени этим нитям (переключения между ними). Сейчас
же речь идет о том, что даже внутри одной нити последовательность команд не всегда
гарантирована. Например, при такой последовательности команд внутри одного из
методов run() или main:

x = 1;

y = 2;

мы не можем быть уверены, что присвоение переменной x произойдет раньше, чем


присвоение переменной y. В приложении с единственной нитью JVM и процессор
берут на себя ответственность, что в логике программы из-за нарушения
последовательности ничего не "поломается". В многопоточном программировании
такая ситуация может привести к проблемам. Например, y стало равным 2, затем
случилось переключение на другую нить (переменная x так и не изменила значение!)
Для решения проблемы существует понятие happens-before (это отношение разных
фрагментов кода друг к другу) и свод правил, которые как раз гарантируют, что один
фрагмент кода будет обязательно полностью выполнен до начала исполнения другого
фрагмента кода. При этом внутри фрагментов перестановки могут по-прежнему быть.

1. все команды в пределах одной нити выполняются исключительно последовательно.


То есть последующая команда не может быть выполнена пропустив текущую.

2. лок на мониторе устанавливается только после того как он был освобожден на этом
же самом мониторе. То есть лок не может быть захвачен другой нитью до тех пор пока
нить, захватившая его, полностью не освободила лок. Иначе смысл лока теряется. К
примеру, вторая нить захватила лок, пока первая его держит. И тут первая
освобождает лок, который все еще нужен второй. Таким образом лок освобождается у
обеих нитей и третья нить может установить свой лок. В итоге белиберда. 3. Примерно
тоже самое что и в п.2. То есть войти в синхронизированный блок возможно только
после того как блок был освобожден другой нитью, фактически когда был полностью
снят лок. 4. Запись поля volatile всегда полностью завершается перед тем как кто-то
его попытается прочитать. 5. Перед тем как нить присоединиться и будет ожидать
другую нить она должна завершить свое выполнение. Было бы не логичным ожидать
завершение в рабочем состоянии. Тоже самое касаемо установки проверки isalive.
Флаг завершения нити устанавливается только после того как нить завершила свою
работу полностью. 6. Ну тут нам все время долбили, что start должен быть в начале.
То есть вызов run не запускает нить, а старт запускает нить и запускает run. 7.
Конструктору дают время на создание нити в любом случае. То есть даже если
вызовется finalize конструктор все равно отработает. Не спрашивайте меня как это
может произойти, я не знаю :) 8. если для нити вызывается interrupt() то она увидит что
вызов пришел только после того как он реально пришел. Возможно этот пункт как-то
перекликается с тем, что wait() надо помещать в цикл. То есть виртуальная машина
сама может чото нагенерить и потом отменить в плане вызова interrupt().
69. Что такое «барьер» в канкаренси?

CyclicBarrier реализует шаблон синхронизации Barrier. Циклический барьер является


точкой синхронизации, в которой указанное количество параллельных потоков
встречается и блокируется. Как только все потоки прибыли, выполняется действие
(или не выполняется, если барьер был инициализирован без него), и, после того, как
оно выполнено, барьер ломается и ожидающие потоки «освобождаются». В
конструктор барьера (CyclicBarrier(int parties) и CyclicBarrier(int parties, Runnable
barrierAction)) обязательно передается количество сторон, которые должны
«встретиться», и, опционально, действие, которое должно произойти, когда стороны
встретились, но перед тем когда они будут «отпущены». Барьер называется cyclic,
потому что его можно использовать повторно после освобождения ожидающих
потоков.

https://www.codeflow.site/ru/article/java-cyclic-barrier

70. Как пользоваться интерфейсом Comparable?

Интерфейс Comparable позволяет сравнивать объекты, используя естественный


порядок сортировки, который будет использоваться в большинстве случаев, в отличие
от специфической сортировки с помощью Comparator.

Прежде всего он удобен для сортировки упорядоченных списков (java.util.List) и


массивов объектов. Если список/массив содержит элементы, реализующие этот
интерфейс, то они могут быть отсортированы автоматически методами
java.util.Collections.sort(List)/Arrays.sort(Object[]).

С интерфейсом Comparable связано понятие натурального упорядочивания, потому


как он устанавливает натуральный порядок следования экземпляров любого класса,
реализующего этот интерфейс.

Интерфейс Comparable является generic’ом – т.е. типом с параметром. У него всего


один generic-метод – int compareTo(T o). В этом методе и происходит сравнение
переданного объекта (o) и текущего (this). Метод возвращает отрицательное число,
если первый объект меньше второго, 0 - если они равны, и положительное число, если
первый объект больше второго. Для реализации данного способа сравнения нужно
унаследовать класс от Comparable <T>, переопределить метод int compareTo() в своем
классе и сравнить в нем текущий объект (this) с переданным.

71. Как пользоваться интерфейсом Comparator?

Comparator - это интерфейс, выполняющий роль шаблона (механизма) сравнения.


Используется для реализации специфической сортировки. При использовании
интерфейса Comparator, логика сравнения пары объектов не прячется внутрь
класса/объекта, а реализуется в отдельном классе. Для его реализации нужно создать
отдельный или анонимный класс, реализующий данный интерфейс и переопределить
в нем метод int compare(T o1, T o2). Логика метода int compare(T o1, T o2) аналогична
методу int compareTo(T o).
72. Как устроен класс ConcurrentHashMap?

К моменту появления ConcurrentHashMap Java-разработчики нуждались в следующей


реализации хэш-карты:

- Потокобезопасность

- Отсутствие блокировок всей таблицы на время доступа к ней

- Желательно, чтобы отсутствовали блокировки таблицы при выполнении операции


чтения

1. Элементы карты

В отличие от элементов HashMap, Entry в ConcurrentHashMap объявлены как volatile.

static final class HashEntry<K, V> {

final K key;

final int hash;

volatile V value;

final HashEntry<K, V> next;

HashEntry(K key, int hash, HashEntry<K, V> next, V value) {

this .key = key;

this .hash = hash;

this .next = next;

this .value = value;

@SuppressWarnings("unchecked")

static final <K, V> HashEntry<K, V>[] newArray(int i) {

return new HashEntry[i];

}
2. Хэш-функция

В ConcurrentHashMap также используется улучшенная функция хэширования.

Напомню, какой она была в HashMap из JDK 1.2:

static int hash(int h) {

h ^= (h >>> 20) ^ (h >>> 12);

return h ^ (h >>> 7) ^ (h >>> 4);

Версия из ConcurrentHashMap JDK 1.5:

private static int hash(int h) {

h += (h << 15) ^ 0xffffcd7d;

h ^= (h >>> 10);

h += (h << 3);

h ^= (h >>> 6);

h += (h << 2) + (h << 14);

return h ^ (h >>> 16);

В чём необходимость усложнения хэш-функции? Таблицы в хэш-карте имеют длину,


определяемую степенью двойки. Для хэш-кодов, двоичные представления которых не
различаются в младшей и старшей позиции, мы будем иметь коллизии. Усложнение
хэш-функции как раз решает данную проблему, уменьшая вероятность коллизий в
карте.

3. Сегменты
Карта делится на N различных сегментов (16 по умолчанию, максимальное значение
может быть 16-битным и представлять собой степень двойки). Каждый сегмент
представляет собой потокобезопасную таблицу элементов карты.

Между хэш-кодами ключей и соответствующими им сегментами устанавливается


зависимость на основе применения к старшим разрядам хэш-кода битовой маски.

Вот как в карте хранятся элементы:

final Segment<K, V>[] segments;

transient Set<K> keySet;

transient Set<Map.Entry<K, V>> entrySet;

transient Collection<V> values;

Рассмотрим, что же представляет из себя класс сегмента:

static final class Segment<K, V> extends ReentrantLock implements

Serializable {

private static final long serialVersionUID = 2249069246763182397L;

transient volatile int count;

transient int modCount;

transient int threshold;

transient volatile HashEntry<K, V>[] table;

final float loadFactor;

Segment(int initialCapacity, float lf) {

loadFactor = lf;

setTable(HashEntry.<K, V> newArray(initialCapacity));

}
...

Учитывая псевдослучайное распределение хэшей ключей внутри таблицы, можно


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

4. ConcurrencyLevel

Данный параметр влияет на использование картой памяти и количество сегментов в


карте.

Посмотрим на создание карты и на то, как влияет заданный в качестве парамента


конструктора concurrencyLevel:

public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {

if (!(loadFactor > 0) || initialCapacity < 0

|| concurrencyLevel <= 0)

throw new IllegalArgumentException();

if (concurrencyLevel > MAX_SEGMENTS)

concurrencyLevel = MAX_SEGMENTS;

// Find power-of-two sizes best matching arguments

int sshift = 0;

int ssize = 1;

while (ssize < concurrencyLevel) {

++sshift;

ssize <<= 1;

segmentShift = 32 - sshift;
segmentMask = ssize - 1;

this .segments = Segment.newArray(ssize);

if (initialCapacity > MAXIMUM_CAPACITY)

initialCapacity = MAXIMUM_CAPACITY;

int c = initialCapacity / ssize;

if (c * ssize < initialCapacity)

++c;

int cap = 1;

while (cap < c)

cap <<= 1;

for (int i = 0; i < this .segments.length; ++i)

this .segments[i] = new Segment<K, V>(cap, loadFactor);

Количество сегментов будет выбрано как ближайшая степень двойки, большая чем
concurrencyLevel. Ёмкость каждого сегмента, соответственно, будет определяться как
отношение округлённого до ближайшей большей степени двойки значения ёмкости
карты по умолчанию, к полученному количеству сегментов. Очень важно понимать две
следующие вещи. Занижение concurrencyLevel ведёт к тому, что более вероятны
блокировки потоками сегментов карты при записи. Завышение показателя ведёт к
неэффективному использованию памяти. Если лишь один поток будет изменять карту,
а остальные будут производить чтение — рекомендуется использовать значение 1.

Итого:

Итак, основные преимущества и особенности реализации ConcurrentHashMap:

- Карта имеет схожий с hashmap интерфейс взаимодействия

- Операции чтения не требуют блокировок и выполняются параллельно

- Операции записи зачастую также могут выполняться параллельно без блокировок

- При создании указывается требуемый concurrencyLevel, определяемый по статистике


чтения и записи

- Элементы карты имеют значение value, объявленное как volatile.


73. Что такое класс Lock?

Для управления доступом к общему ресурсу в качестве альтернативы оператору


synchronized мы можем использовать блокировки. Функциональность блокировок
заключена в пакете java.util.concurrent.locks.

Вначале поток пытается получить доступ к общему ресурсу. Если он свободен, то на


поток на него накладывает блокировку. После завершения работы блокировка с
общего ресурса снимается. Если же ресурс не свободен и на него уже наложена
блокировка, то поток ожидает, пока эта блокировка не будет снята.Классы блокировок
реализуют интерфейс Lock, который определяет следующие методы:

- void lock(): ожидает, пока не будет получена блокировка

- boolean tryLock(): пытается получить блокировку, если блокировка получена, то


возвращает true. Если блокировка не получена, то возвращает false. В отличие от
метода lock() не ожидает получения блокировки, если она недоступна

- void unlock(): снимает блокировку

- Condition newCondition(): возвращает объект Condition, который связан с текущей


блокировкой

Организация блокировки в общем случае довольно проста: для получения блокировки


вызывается метод lock(), а после окончания работы с общими ресурсами вызывается
метод unlock(), который снимает блокировку. Объект Condition позволяет управлять
блокировкой. Как правило, для работы с блокировками используется класс
ReentrantLock из пакета java.util.concurrent.locks. Данный класс реализует интерфейс
Lock.

74. Что такое итератор?

Это объект, реализующий интерфейс Iterator. Java интерфейс java.util.Iterator


обеспечивает итерацию контейнерных классов. Каждый Iterator реализует методы
next() и hasNext() и дополнительно может поддерживать метод remove(). Итераторы
создаются соответствующими контейнерными классами, как правило методом
iterator().

Реализация интерфейса предполагает, что с помощью вызова метода next() можно


получить следующий элемент. С помощью метода hasNext() можно узнать, есть ли
следующий элемент, и не достигнут ли конец коллекции. И если элементы еще
имеются, то hasNext() вернет значение true. Метод hasNext() следует вызывать перед
методом next(), так как при достижении конца коллекции метод next() выбрасывает
исключение NoSuchElementException.

Метод next() переводит итератор на следующее значение и возвращает указываемое


значение итератору. При первоначальном создании итератор указывает на
специальное значение, находящееся перед первым элементом, поэтому первый
элемент можно получить только после первого вызова next(). Для определения
момента, когда все элементы в контейнере были перебраны, используется тестовый
метод hasNext().
И метод remove() удаляет текущий элемент, который был получен последним вызовом
next().

Интерфейс Iterator предоставляет ограниченный функционал. Гораздо больший набор


методов предоставляет другой итератор - интерфейс ListIterator. Данный итератор
используется классами, реализующими интерфейс List, то есть классами LinkedList,
ArrayList и др.

75. goto - оператор безусловного перехода (перехода к определённой точке


программы, обозначенной номером строки либо меткой) в некоторых языках
программирования. Java не содержит оператора goto, потому что он выполняет
переход произвольным и неструктурированным способом. Код, интенсивно
использующий goto, обычно трудно понять и поддерживать. Он также отменяет
некоторые оптимизации компилятора.

Вместо него в Java используется break с меткой, имеющий следующую общую форму:
break label; Здесь label — имя метки, которая идентифицирует некоторый блок кода.
Когда эта форма break выполняется, управление передается из именованного блока
кода (чья метка указана в операторе break) на следующий за этим блоком оператор.

Метка — это любой допустимый идентификатор Java, за которым следует двоеточие.

76. Что такое зарезервированные слова в Java?

Это ключевые слова, которые не используются в языке Java. Использовать их в


качестве названия полей, методов объектов нельзя.

77. Что произойдет, если вызвать wait не в блоке synchronized?

Код выбросит IllegalMonitorStateException.

Поскольку условие вызова wait() задается отдельным потоком, то для правильной


работы этого метода необходима синхронизация.

78. Как скомпилировать java-файл из консоли?

Переходим в каталог, где лежит данный файл, и запускаем команду:

javac fileName.java

https://javarush.ru/groups/posts/2318-kompiljacija-v-java

https://habr.com/ru/post/125210/
79. Как запустить java-файл из консоли?

Переходим в каталог, где лежит данный файл, и запускаем команду:

java fileName

80. Как запустить программу из нескольких скомпилированных файлов из консоли?

https://javarush.ru/groups/posts/2318-kompiljacija-v-java

Создать classpath. Он похож на файловую систему, в которой содержатся классы, а


функцию папок выполняют пакеты (packages). На этом этапе стоит задуматься об
отделении файлов исходного кода от скомпилированных файлов. Как правило
исходники находятся в каталоге src, а скомпилированные классы — в bin. Создаем
папки src и bin.

В коде прописываем package:

package src;

public class Box {

package src;

public class BoxMachine {

public static void main(String[] args) {

Чтобы скомпилировать эту группу классов, необходимо из главного каталога (в


котором лежат папки src и bin) использовать команду javac с аргументами:

javac -d bin ./src/*

-d — флаг, после которого следует указать расположение, куда попадут


скомпилированные классы. Это очень удобно, так как перекладывать, например, 1000
классов — очень трудоемкий процесс.

bin — название папки.

./src/* — расположение исходных файлов. * указывает, что необходимо


скомпилировать все файлы. Теперь скомпилированные классы появились в папке bin.

Для их запуска используется команда java из той же директории, также с аргументами:


java -classpath ./bin src.BoxMachine

81. Как создать директорию с поддиректориями: (doc/release/com/javarush/test)?

new File("c:/doc/release/com/javarush/test").mkdirs();

82. Как получить список файлов в директории по маске (шаблону) «*.doc»?

С помощью метода public File[] listFiles(FilenameFilter filter) объекта типа java.io.File

File f = new File("c:/MyDocs");

//Cписок файлов без фильтра

System.out.println(Arrays.toString(f.listFiles()));

//А вот так получаем только *.doc файлы

File[] docs= f.listFiles(

(dir, name) -> {

return name.toLowerCase().endsWith(".doc");

);

System.out.println(Arrays.toString(docs));

83. Назначение и методы класса BlockingQueue?

Интерфейс BlockingQueue определяет блокирующую очередь, наследующую свойства


интерфейса Queue, в которой элементы хранятся в порядке «первый пришел, первый
вышел» (FIFO – first in, first out). Реализация данного интерфейса обеспечивает
блокировку потока в двух случаях: при попытке получения элемента из пустой
очереди; при попытке размещения элемента в полной очереди.

Когда поток пытается получить элемент из пустой очереди, то он переводится в


состояние ожидания до тех пор, пока какой-либо другой поток не разместит элемент в
очереди. Аналогично при попытке положить элемент в полную очередь; поток ставится
в ожидание до тех пор, пока другой поток не заберет элемент из очереди и, таким
образом, не освободит место в ней.

Предназначена для реализации взаимодействия "поставщик - потребитель".


Реализации методов потокобезопасны (синхронизированы), так что и писать в нее, и
читать из неё можно в несколько потоков. Естественно, понятие "полная очередь"
подразумевает ограничение размера очереди. BlockingQueue изящно решает
проблему передачи собранных одним потоком элементов для обработки в другой
поток без явных хлопот о проблемах синхронизации.

Методы:

boolean add(E e) - Немедленное добавление элемента в очередь, если это возможно;


метод возвращает true при благополучном завершении операции, либо вызывает
IllegalStateException, если очередь полная.

boolean contains(Object o) - Проверка наличия объекта в очереди; если объект найден


в очереди метод вернет true.

boolean offer(E e) - Немедленное размещение элемента в очереди при наличие


свободного места; метод вернет true при успешном завершении операции, в
противном случае вернет false.

boolean offer(E e, long timeout, TimeUnit unit) - Размещение элемента в очереди при
наличии свободного места; при необходимости определенное ожидание времени, пока
не освободиться место.

E poll(long timeout, TimeUnit unit) - Чтение и удаление элемента из очереди в течение


определенного времени (таймаута).

void put(E e) - Размещение элемента в очереди, ожидание при необходимости


освобождения свободного места.

int remainingCapacity() - Получения количества элементов, которое можно разместить в


очереди без блокировки, либо Integer.MAX_VALUE при отсутствии внутреннего
предела.

boolean remove(Object o) - Удаление объекта из очереди, если он в ней присутствует.

E take() - Получение с удалением элемента из очереди, при необходимости ожидание


пока элемент не станет доступным.

BlockingQueue не признает нулевых элементов (null) и вызывает NullPointerException


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

84. Что такое дедлок?

Deadlock— это взаимная блокировка нескольких нитей, которая происходит, когда


нити имеют циклическую зависимость от пары синхронизированных объектов.
Например, ситуация, когда одна нить входит в монитор объекта x, а другая — объекта
y. Если нить в объекте x пытается вызвать любой синхронизированный метод объекта
y, а объект y в то же самое время пытается вызвать любой синхронизированный
метод объекта x, то нити застрянут в процессе ожидания.

85. Какие вы знаете стратегии, предотвращающие появление дедлоков?


Необходимо проводить проверку кода и тестирование.

- В случае взаимной блокировки порядка синхронизации необходимо ввести порядок


входа нитей в мониторы объектов. Например, если хэш-код (или другая численная
величина, относящаяся к объекту) объекта А меньше Б, то сначала нить входит в
монитор А, затем Б, или наоборот. Если хэш-коды объектов совпадут, то можно
добавить 3-й объект, например Object lock.

- В случае взаимной блокировки между объектами (например, синхронизированные


методы двух классов вызывают внутри себя синхронизированные методы друг друга)
рекомендуется использовать открытые вызовы к методам других объектов. То есть,
переписать методы и вызывать методы других объектов вне синхронизированного
блока.

Также можно использовать интерфейс Lock и его реализации доступные в пакете


java.util.concurrent.locks, которые позволяют попытаться занять монитор, связанный с
экземпляром данного класса методом tryLock (возвращает true, если удалось занять
монитор).

86. Могут ли возникнуть дедлоки при использовании методов wait-notify?

Дедлоков можно избежать за счет разумного использования synchronized, volatile,


монитора (wait(), notify(), notifyAll()),а если копать глубже, то используя классы
java.utils.concurrent: вместо обычных коллекций - многопоточные варианты
(ConcurrentHashMap, например); если нужен более сложный способ синхронизации
потоков — различные CyclicBarrier, CountDownLatch.Если грамотно использовать wait
– notify, то дедлоки возникнуть не должны.)))

87. Что чаще используется: notify или notifyAll?

В зависимости от программы.

88. Метод wait рекомендуется использовать с конструкциями if или while?

Дело в том, что notify может вызвать кто угодно. Просто по ошибке, от которой никто
не застрахован. Если поток ждет выполнения некоторого условия – вариант с while
надежнее. Если поток пустили по ошибке – он опять проверит условие и, если надо,
будет ждать дальше.

89. Что происходит после вызова метода notifyAll?

Пробуждаются все нити, которые ждали на мониторе объекта, у которого вызвали


notifyAll().

90. Какие выгоды получает объект, если он immutable?


Неизменяемым (immutable) называют объект, которого невозможно изменить после
инициализации. К таким относятся String, все классы-обертки над примитивными
типами, объекты класса java.lang.StackTraceElement.

В случае многопоточного программирования преимущества immutable классов


заключаются в том, что после создания объекты можно передавать другим потокам и
они всегда будут в актуальном состоянии. Т.е. нам не надо проверять не устарело ли
состояние нашего экземпляра и не модифицировал ли его другой поток пока мы с ним
работаем. Неизменяемые объекты не требуют синхронизации при многопоточном
доступе.

91. Что такое «thread-safe»?

Состояние потокобезопасности подразумевает, что метод или класс может быть


использован множеством нитей без проблем столкновения, то есть дедлоков.

92. Что такое JMM?

https://habr.com/ru/post/440590/

Это модель памяти в Java — (Java Memory Model), которая предоставляет некоторые
правила для написания корректного многопоточного кода.

- Конкуренция — это способ одновременного решения множества задач.

- Параллелизм — это способ выполнения разных частей одной задачи.

- Модель исполнения через чередование операций.

- Модель happens-before

93. Какое исключение вылетит, если вызвать wait не в блоке synchronized?

Код выбросит IllegalMonitorStateException.

94. Как получить список живых нитей из группы ThreadGroup?

С помощью метода public int activeCount() и public int enumerate(Thread[] list,boolean


recurse) класса ThreadGroup.

Thread[] temp = new Thread[thG.activeCount()];

thG.enumerate(temp);

возвращает приблизительное количество активных потоков в этой группе


activeCount
потоков и ее подгруппах. Рекурсивно перебирает все подгруппы в этой группе потоков.
enumerateкопирует в указанный массив каждый активный поток в этой группе потоков.
Если recurse - true, этот метод рекурсивно перечисляет все подгруппы этой группы
потоков, и также включаются ссылки на каждый активный поток в этих подгруппах.
Если массив слишком короткий, чтобы вместить все потоки, дополнительные потоки
игнорируются.

https://coderoad.ru/1323408/Получить-список-всех-потоков-запущенных-в-данный-
момент-в-Java

95. Как получить список мертвых нитей из группы ThreadGroup?

Т.к. cсылка на нить удаляется из группы после выполнения и у нити удаляется ссылка
на группу, после того как нить завершиться, можно понять, что, не подготовившись
заранее, нельзя получить список завершенных нитей, группа о них уже не помнит, как
и они о ней.

Нужно заранее сохранять где-нибудь ссылку на нить.

https://javarush.ru/groups/posts/1328-kak-poluchitjh-spisok-mertvihkh-nitey-iz-gruppih-
threadgroup-level-28?post=full#discussion

96. Аналоги ThreadPoolExecutor?

executorservice

forkjoinpool

newfixedthreadpool

threadpooltaskexecutor

scheduledthreadpoolexecutor

97. Что такое ThreadWorker?

ThreadWorker запускает задачи в отдельном потоке, где задачи ставятся в очередь и


выполняются одна за другой. Java 1.5 делает этот класс несколько устаревшим, но он
все еще там, поскольку он использовался в других местах в этой среде. Начиная с JDK
1.5 FCS, эта реализация принята для реализации Executor.

98. Что такое ThreadPool?

Пул потоков, позволяющий повторно использовать ранее созданные потоки для


выполнения текущих задач, тем самым снижая потребление ресурсов. Поскольку к
моменту поступления запроса поток уже существует, то задержка, вызванная
созданием потока, устраняется, что делает приложение более отзывчивым.
99. Что такое FactoryMethod?

Фабричный метод или виртуальный конструктор (Virtual Constructor) — порождающий


шаблон проектирования, предоставляющий дочерним классам интерфейс для
создания экземпляров некоторого класса. В момент создания наследники могут
определить, какой класс создавать. Иными словами, данный шаблон делегирует
создание объектов наследникам родительского класса. Это позволяет использовать в
коде программы не специфические классы, а манипулировать абстрактными
объектами на более высоком уровне.

Product — определяет интерфейс объектов создаваемых абстрактным методом;

ConcreteProduct —реализует интерфейс Product;

Creator — объявляет фабричный метод, который возвращает объект типа Product.


Может также содержать реализацию этого метода «по умолчанию»;

может вызывать фабричный метод для создания объекта типа Product;

ConcreteCreator —переопределяет фабричный метод таким образом, чтобы он


создавал и возвращал объект класса ConcreteProduct.

https://ru.wikipedia.org/wiki/Фабричный_метод_(шаблон_проектирования)#Java

100. Что такое DDD?

Предметно-ориентированное проектирование (Domain-driven design) - это набор


принципов и схем, направленных на создание оптимальных систем объектов.
Сводится к созданию программных абстракций, которые называются моделями
предметных областей. В эти модели входит бизнес-логика, устанавливающая связь
между реальными условиями области применения продукта и кодом.

Область (англ. domain, домен) — предметная область, к которой применяется


разрабатываемое программное обеспечение.

Модель (англ. model) — описывает отдельные аспекты области и может быть


использована для решения проблемы.

Язык описания — используется для единого стиля описания домена и модели.

101. Что такое TDD?

Разработка через тестирование (англ. test-driven development, TDD) — техника


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

102. Что такое dump?


Дамп памяти (англ. memory dump; в Unix — core dump) — выгрузка содержимого
рабочей памяти одного процесса, ядра или всей операционной системы. Также может
включать дополнительную информацию о состоянии программы или системы,
например значения регистров процессора и содержимое стека. Многие операционные
системы позволяют сохранять дамп памяти для отладки программы. Как правило,
дамп памяти процесса сохраняется автоматически, когда процесс завершается из-за
критической ошибки (например, из-за ошибки сегментации). Дамп также можно
сохранить вручную через отладчик или любую другую специальную программу.

103. Что такое Pool?

Пул - по сути это "множество", "набор" чего-либо (объединенного по какому-то либо


признаку). На практике это может быть:

- некоторой областью памяти, используемая для хранения данных или исполняемого


кода, имеющего общие признаки - так например - объектный пул(link is external);

-набором каких-либо программных сущностей (типа классов, функций и т.д.).

104. Какие приоритеты нитей бывают?

Для оптимизации параллельной работы нитей в Java имеется возможность


устанавливать приоритеты нитей. Приоритет – это некоторое число в объекте потока
от 1 до 10.

Нити с большим приоритетом имеют преимущество в получении времени процессора


перед нитями с более низким приоритетом. Работа с приоритетами обеспечивается
следующими методами класса Thread:

public final void setPriority(int newPriority)- Устанавливает приоритет нити.

public final int getPriority()- Позволяет узнать приоритет нити.

При своем создании нить имеет приоритет NORM_PRIORITY.

MIN_PRIORITY = 1.NORM_PRIORITY =5.MAX_PRIORITY = 10.

Приоритет нити не сильно влияет на ее работу, а носит скорее рекомендательный


характер. Если есть несколько спящих нитей, которые нужно запустить, то Java-
машина сначала запустит нить с более высоким приоритетом. Java-машина управляет
нитями так, как посчитает нужным. Нити с низким приоритетом не будут простаивать.
Просто они будут получать меньше времени, чем другие, но выполняться все равно
будут. В большинстве случаев нити всегда выполняются с одинаковым приоритетом.
Попытка дать одной нити больше времени, чем другим, часто указывает на
архитектурную ошибку программы.

105. Можно ли остановить нить, снизив ее приоритет до 0?

Нет. Будет брошен IllegalArgumentException


106. Зачем нужен класс ThreadGroup?

ThreadGroup – это класс, который управляет группами нитей. Такой подход сделан для
того, чтобы нить не могла останавливать и прерывать все нити подряд, а могла
оказывать влияние только на те нити, которые содержатся в той же группе, что и она.

107. В какой группе нитей состоит main-thread?

группа main

108. Что такое паттерн ThreadPool?

Паттерн ThreadPool общими словами - группа потоков, которые решают группы задач.
Задачи организованы в очередь. Как только поток завершает работу над задачей, он
запрашивает следующую задачу из очереди, до тех пор, пока все задачи в очереди не
будут выполнены. После этого поток может завершиться, либо уснуть, до тех пор, пока
в очереди не появятся новые задачи.

109. Зачем нужен класс ThreadPoolExecutor?

Для решения большого количества небольших задач группой потоков. Использование


класса позволяет избегать чрезмерного использования ресурсов машины, т.к. на
создание нити Java-машина выделяет много ресурсов. Создание и уничтожение
отработавшей нити может тратить больше ресурсов и времени, чем само
выполняемое задание.

Класс ThreadPoolExecutor имеет внутри очередь задач, в которую можно добавлять


задачи, по мере их появления в программе, и пул нитей, которые эти задачи
исполняют. При этом нити не уничтожаются после выполнения задания, а засыпают,
чтобы начать выполнять новое задание, как только оно появится.

110. Сколько способов создать нить вы знаете?

Thread, Runnable, Callable<T>

public class ThreadsTests {

//Способ 1

static class ThreadExampleRunnable implements Runnable{

@Override

public void run() {


System.out.println(Thread.currentThread().getName());

//Способ 2

static class ThreadExampleFromThread extends Thread {

@Override

public void run() {

System.out.println(Thread.currentThread().getName());

//Способ 3

static class ThreadExampleFromCallable implements Callable{

@Override

public String call() throws Exception {

return Thread.currentThread().getName();

public static void main(String[] args) throws ExecutionException, InterruptedException {

new Thread(new ThreadExampleRunnable()).start(); //Способ 1

new ThreadExampleFromThread().start(); //Способ 2

//Способ 3

ExecutorService service = Executors.newFixedThreadPool(5);

Future task = service.submit(new ThreadExampleFromCallable());


System.out.println(task.get());

}
}

111. Для чего используется класс Future?

Для того, чтобы узнать, завершилось ли уже выполнение задачи, а также, чтобы
получить результат ее выполнения.

boolean cancel(boolean mayInterrupt); // пытается остановить задачу.

boolean isCancelled(); //возвращает true, если задача была остановлена.

boolean isDone(); //возвращает true, если выполнение задачи завершено.

V get() throws InterruptedException, ExecutionException; //возвращает результат вызова


метода call или кидает исключение, если оно было. При необходимости ожидает
завершения вычисления.

112. В чем преимущества Callable над Runnable?

Используя Callable можно узнать завершилась ли задача, и узнать её результат.

113. Можно ли отменить выполнение задачи, если использовать класс Future?

С помощью метода cancel() класса Future можно попытаться отменить выполнение


задачи. Однако, данная попытка окажется неудачной, если задача уже выполнена,
была отменена или не может быть отменена по какой-либо другой причине.

114. Что такое autoboxing?

Это автоматическая инкапсуляция примитивного типа в эквивалентную ему класс-


обёртку всякий раз, когда требуется объект данного типа.

Autoboxing происходит:

- При присвоении значения примитивного типа переменной соответствующего класса-


обёртки.

- При передаче примитивного типа в параметр метода, ожидающего соответствующий


ему класс-обёртку.

Распаковка (unboxing) — конвертация класса-обёртки в соответствующий ему


примитивный тип. В процессе распаковки может произойти исключение
java.lang.NullPointerException , если значение переменной равно null.

115. Зачем используется autoboxing?


Для удобства при использовании арифметических операций и операций сравнения
(исключение == и !=).

116. Альтернативы autoboxing?

Альтернатива - создание и инициализация объектов-оберток с помощью метода


valueOf() или с помощью конструктора.

117. Типы-обертки для примитивных типов mutable или immutable?

Immutable

118. Как примитивные типы приводятся к непримитивным аналогам?

Метод valueOf() или через конструктор (н-р, new Integer(10)) чтобы преобразовать
примитивные типы в непримитивные.

119. Как непримитивные типы приводятся к примитивным?

Методы IntValue(), doubleValue() и т.д., чтобы получить примитивные типы из


непримитивных.

120. Как сравниваются примитивные и непримитивные типы?

Примитивные типы сравниваются с помощью операторов >, <, >=, <=, ==. Классы-
обертки сравниваются с помощью методов equals() и compareTo(). Если сравнивается
примитивный и непримитивный тип с помощью вышеперечисленных операторов, то
перед сравнением будет распаковано значение из непримитивного типа.

121. Всегда ли создается новый объект при операции autoboxing?

При автоупаковке создается новый объект, если примитив с любым значением


упаковывается в объект Double или Float, а также если примитив со значением
меньше -128 или больше 127 упаковывается в объект Short, Integer, Long, Character.

Во всех остальных случаях значения происходит кэширование значений.

122. Как работает кэширование при операции autoboxing?


При автоупаковке фактически вызывается статичный метод XXX.valueOf(), который
кэширует значения от -128 до 127 и при повторном использовании достает их из пула
констант (набор инициализированных и готовых к использованию объектов).

123. Для каких типов и/или значений работает кэширование?

Кэширование работает для следующих типов объектов:

- Byte - для всех значений

- Short- от -128 до +127

- Integer - от -128 до +127

- Long - от -128 до +127

- Character - от 0 до 127

- Boolean - все значения

124. Как преобразовать число из одной системы счисления X в другую Y?

String number = new BigInteger("число", X).toString(Y);

125. Что такое base64?

Это алгоритм для кодирования двоичных данных при помощи только 64 символов
ASCII. Алфавит кодирования содержит текстово-цифровые латинские символы A-Z, a-
z и 0-9 (62 знака) и 2 дополнительных символа, зависящих от системы реализации.
Каждые 3 исходных байта кодируются 4 символами (увеличение на ¹⁄₃). Эта система
широко используется в электронной почте для представления бинарных файлов в
тексте письма (транспортное кодирование).

126. Что произойдет, если поместить оператор return или System.exit () в блок
try/catch/finally?

Блок finally будет выполняться при помещении оператора return в блок try/catch, и не
будет выполняться при вызове из блока try/catch оператора System.exit ().

127. Поддерживает ли язык Java множественное наследование?

Нет, но за счет реализации интерфейса, расширяющего другие интерфейсы можно


добиться множественного наследования типов.
128. В случае, когда метод генерирует исключение NullPointerException в
родительском классе, можно ли его переопределить методом, генерирующим
RuntimeException?

Можно.

129. Как гарантировать возможность обращения N нитей к N ресурсам без взаимной


блокировки?

Предотвратить взаимную блокировку можно благодаря освобождению ресурсов в


порядке, обратном порядку их получения.

130. В чем разница между классами StringBuffer и StringBuilder в языке Java?

Методы класса StringBuffer синхронизированы, в то время как соответствующие


методы класса StringBuilder – нет. Конкатенация строк при помощи StringBuilder
выполняется быстрее, чем с помощью StringBuffer.

131. Что вернет выражение 1.0/0.0? Приведет ли оно к генерации исключения или
ошибке при компиляции?

Вернет Double. POSITIVE_INFINITY. Генерации ArithmeticException не произойдет.

132. Что будет, если попытаться вставить в HashMap уже имеющийся в ней ключевой
объект?

К имеющемуся ключу будет перезаписано новое значение.

133. Что такое NaN?

NaN (англ. Not-a-Number) — одно из особых состояний числа с плавающей запятой.


Используется во многих математических библиотеках и математических
сопроцессорах. Данное состояние может возникнуть в различных случаях, например,
когда предыдущая математическая операция завершилась с неопределённым
результатом, или если в ячейку памяти попало не удовлетворяющее условиям число.

К операциям, приводящим к появлению NaN в качестве ответа, относятся:

-все математические операции, содержащие NaN в качестве одного из операндов;

-деление нуля на нуль;

-деление бесконечности на бесконечность;

-умножение нуля на бесконечность;


-сложение бесконечности с бесконечностью противоположного знака;

-вычисление квадратного корня отрицательного числа;

-логарифмирование отрицательного числа.

134. Как получить бесконечность в Java?

Положительное число, разделенное на 0.0, дает «плюс бесконечность», а


отрицательное – «минус бесконечность».

public static final double POSITIVE_INFINITY = 1.0 / 0.0;

public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

Выражение Результат

n ÷ ±Infinity 0

±Infinity * ±Infinity ±Infinity

Infinity + Infinity Infinity

Infinity - Infinity NaN

±Infinity ÷ ±Infinity NaN

±Infinity × 0 NaN

135. Как проверить, что в результате вычисления получилась бесконечность?

Методом isInfinite(float/double), возвращающим true, если число-аргумент +-


бесконечность.

Либо методом isFinite(float/double), возвращающим true, если число-аргумент - не


бесконечность.
136. Что такое битовая маска?

Битовая маска — определённые данные, которые используются для маскирования —


выбора отдельных битов или полей из нескольких битов из двоичной строки или
числа. Это алгоритм хранения логических значений (true/false, каждому из которых
соответствует определенный бит) в виде некоторого целого числа.

137. Где применяют битовые маски?

Основные плюсы и недостатки:

-Экономия памяти — требуется бит для хранения информации, а не байт.

Сфера использования в основном в интерфейсах, где приоритет отдаётся экономии


памяти:

-выбор битов из слова состояния, идущие с пакетом по интерфейсу, например,


контрольная сумма;

-выбор битов из IP-адреса для адресации подсети (см. маска подсети) 255.255.224.0

138. Как установить бит в единицу в битовой маске?

result |= (1<<n); // result - исходное число, n - номер бита.

139. Как установить бит в ноль в битовой маске?

result &= ~(1<<n); // result - исходное число, n - номер бита.

140. Как получить значение определенного бита в битовой маске?

с = result & (1<<n); // result - исходное число, n - номер бита.

141. Что такое ленивое вычисление выражения?

Ленивые вычисления (англ. lazy evaluation, также отложенные вычисления) —


применяемая в некоторых языках программирования стратегия вычисления, согласно
которой вычисления следует откладывать до тех пор, пока не понадобится их
результат. Отложенные вычисления позволяют сократить общий объём вычислений
за счёт тех вычислений, результаты которых не будут использованы. Логические
выражения вычисляются слева направо и в них (в логических выражениях) работает
принцип ленивых вычислений - вычислений только при необходимости. Если при
вычислении части выражения ответ уже и так понятен, то остальная часть выражения
не вычисляется.

142. Чем отличается использование && и & для типа boolean?

При использовании && с типами boolean правая часть выражения вычисляется, только
если левая часть дает результат true. Иначе правая часть не вычисляется, т.к. всё
выражение становится false вне зависимости от правой части. Т.е. происходят
ленивые вычисления.

143. Как получить список всех файлов в директории и ее поддиректориях?

- С помощью метода Files.walkFileTree(Path start, FileVisitor<? super Path> visitor).


Возвращает объект Path - путь к файлу.

- С помощью метода класса File - listFiles() + рекурсия (для прохождения всех


подкаталогов пути). Возвращает массив строк - полных имен файлов.

144. Как получить список всех файлов в директории с расширением zip?

try(ZipInputStream zin = new ZipInputStream(new FileInputStream ("C:\\zipFile.zip"))) {

ZipEntry entry;

String name;

while((entry=zin.getNextEntry())!=null){

name = entry.getName(); // получаем название 1 файла

//в цикле получаем названия всех файлов в архиве ZIP

zin.closeEntry();

145. Как заархивировать файл?

Для создания архива используется класс ZipOutputStream. Для создания объекта


ZipOutputStream в его конструктор передается поток вывода:
ZipOutputStream(OutputStream out).
Для записи файлов в архив для каждого файла создается объект ZipEntry, в
конструктор которого передается имя архивируемого файла. А чтобы добавить
каждый объект ZipEntry в архив, применяется метод putNextEntry().

String filename = "C:\\SomeDir\\notes.txt";//файл для архивации

try(ZipOutputStream zout = new ZipOutputStream(new FileOutputStream("C:\\output.zip"));

FileInputStream fis= new FileInputStream(filename);) {

ZipEntry entry1=new ZipEntry("notes.txt");

zout.putNextEntry(entry1);

// считываем содержимое файла в массив byte

int size;

byte[] buffer = new byte[1024];

while((size = fis.read(buffer, 0, buffer.length))> -1) {

zout.write(buffer);

// добавляем содержимое к архиву

либо

Path path = Paths.get(filename);

Files.copy(path, zout);

// закрываем текущую запись для новой записи

zout.closeEntry();

146. Как заархивировать много файлов?

Проходимся методом Files.walkFileTree() по директории с файлами и архивируем


каждый полученный объект Path:

Files.walkFileTree(Paths.get("E:\\zipfolder"), new Test2());


try(ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("E:\\zipfolder.zip")))
{

for (Path path: pathList) {

//в качестве имени берем только имя файла без папок

String fileName = path.toString().substring(path.toString().lastIndexOf("\\") + 1);

ZipEntry entry = new ZipEntry(fileName);

zos.putNextEntry(entry);

Files.copy(path, zos);

zos.closeEntry();

147. Как заархивировать много файлов и директорий?

Проходимся методом Files.walkFileTree() по директории с файлами и архивируем


каждый полученный объект Path:

public class Test2 extends SimpleFileVisitor<Path> {

static List<Path> pathList = new ArrayList<>();

public static void main(String[] args) throws IOException {

Files.walkFileTree(Paths.get("E:\\zipfolder"), new Test2());

try(ZipOutputStream zos = new ZipOutputStream(new


FileOutputStream("E:\\zipfolder.zip"))) {

for (Path path: pathList) {

if (Files.isRegularFile(path)) {

//копируем файлы в архив

String fileName = path.toString().substring(path.toString().indexOf("\\") + 1);

ZipEntry entry = new ZipEntry(fileName);

zos.putNextEntry(entry);
Files.copy(path, zos);

} else if (Files.isDirectory(path)) {

//создаем папки в архиве

String directory = path.toString().substring(path.toString().indexOf("\\") + 1);

ZipEntry entry = new ZipEntry(directory + "\\");

zos.putNextEntry(entry);

zos.closeEntry();

@Override

public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {

pathList.add(file);

return super.visitFile(file, attrs);

@Override

public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws


IOException {

pathList.add(dir);

return super.preVisitDirectory(dir, attrs);

148. Как разархивировать файл?

//Пример для архива из нескольких файлов и папок

try (ZipInputStream zis = new ZipInputStream(new FileInputStream("E:\\zipfolder.zip"))) {


ZipEntry entry;

while ((entry = zis.getNextEntry())!= null) {

Path path = Paths.get("E:\\" + entry.getName());

if (!Files.exists(path)) {

Files.createDirectories(Paths.get(path.toString().substring(0,
path.toString().lastIndexOf("\\") + 1)));

Files.copy(zis, path, StandardCopyOption.REPLACE_EXISTING);

или

try (FileOutputStream fos = new FileOutputStream(path.toString())) {

int size;

byte[] buffer = new byte[1024];

while ((size = zis.read(buffer, 0, buffer.length)) > -1) {

fos.write(buffer, 0, size);

149. Как задать кодировку файла?

Задать кодировку можно в конструкторе

- Files.newBufferedReader(Path path, Charset cs) для чтения файла в поток


BufferedReader;

- Files.newBufferedWriter(Path path, Charset cs, OpenOption... options) для записи файла


в поток BufferedWriter;

- Files.readAllLines(Path path, Charset cs) для чтения всех строк файла в List<String>;

- Files.write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption...


options) для записи списка строк lines в файл path;

- в конструкторе InputStreamReader(InputStream in, String charsetName) для чтения;

- в конструкторе OutputStreamWriter(OutputStream out, String charsetName) для записи;


150. Как узнать кодировку файла в архиве?

Либо способом подбора либо с помощью сторонних библиотек или декодеров.

151. Как поменять данные (свойства) в объекте типа Properties?

properties.setProperty("name","Sergio");//указываем пару ключ-значение

Чтобы (пере)записать файл properties с новым значением вызываем:

properties.store(new FileWriter(filename), "comment");

//filename - адрес файла properties

152. Может ли объект File соответствовать файлу, которого еще нет?

Объект класса File является абстрактным представлением файла и пути к нему. Он


устанавливает только соответствие с ним, при этом для создания объекта неважно,
существует ли такой файл на диске. После создания можно выполнить проверку,
вызвав метод exists, который возвращает значение true, если файл существует.
Создание или удаление объекта класса File никоим образом не отображается на
реальных файлах. Для работы с содержимым файла можно получить экземпляры File
I/O Stream.

Объект File может указывать на каталог (узнать это можно путем вызова метода
isDirectory ). Метод list возвращает список имен (массив String ) содержащихся в нем
файлов (если объект File не указывает на каталог – будет возвращен null ).

153. Как преобразовать объект File к типу Path?

Методом toPath().

154. Зачем нужен класс Files?

Files — это утилитный класс, куда были вынесены статические методы из класса File
(по аналогии с Arrays или Collections). Он сосредоточен на управлении файлами и
директориями.

155. Какие классы для архивации вы знаете?

Для работы с архивами в спецификации Java существуют два пакета – java.util.zip и


java.util.jar.
156. Как добавить директорию в архив?

try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream("c:/archive.zip"))){

out.putNextEntry(new ZipEntry("myfolder/"));

} catch (IOException e){

e.printStackTrace();

157. Зачем нужны Properties?

Это специальные файлы, в которых хранятся текстовые данные (например,


конфигурационные параметры прикладного ПО) в виде пар (ключ-значение). Файлы с
расширением «.properties» являются обычными текстовыми файлами. Просматривать
и изменять такие файлы можно в любом текстовом редакторе. Каждая строка файла
обычно содержит один «параметр», который состоит из пары объектов строкового
типа «ключ» (имя параметра) — «значение», записанной в одном из следующих
форматов: ключ=значение, ключ = значение, ключ:значение и ключ : значение.

Например,

Файл data.properties

directory=c:/text/downloads

email=zapp@javarush.ru

158. В каком виде хранятся данные в файле .properties?

Каждая строка файла обычно содержит один «параметр», который состоит из пары
объектов строкового типа «ключ» (имя параметра) — «значение», записанной в одном
из следующих форматов: ключ=значение, ключ = значение, ключ:значение и ключ :
значение.

159. Можно ли изменять данные в объекте Properties после загрузки их из файла?

С помощью метода setProperty(String key, String value).

160. Зачем нужен класс FileReader?

Для чтения файлов (посимвольно). Является наследником абстрактного класса


Reader.
161. Зачем нужен класс FileWriter?

Для записи файлов (посимвольно). Является наследником абстрактного класса Writer.

162. Как записать информацию в файл в произвольном месте?

RandomAccessFile raf = new RandomAccessFile("E:\input.txt", "rw");

raf.seek(100);//перемещаем курсор перед 100-ым байтом

raf.writeBytes("It is a string");//пишем строку в файл начиная с 100-го байта

163. Как прочитать 10000-ю строку из файла, не читая предыдущих?

Никак, не прочитав предыдущие 9999 строк, или не зная номер байта начала этой
строки.

164. Как преобразовать строку в Reader?

Reader reader = new StringReader("Строка");

165. Как преобразовать Writer в строку?

Writer writer = new StringWriter();

writer.write("Строка");

String output = writer.toString();

166. Как создать прокси-объект?

Создать оригинальный объект

Получить загрузчик классов ClassLoader loader = original.getClass().getClassLoader();

Получить все интерфейсы, которые реализуют оригинал

Class[] interfaces = original.getClass().getInterfaces();

Используем специальный класс Proxy и его статический метод newProxyInstance() и


приводим объект к интерфейсу

Proxy.newProxyInstance(loader, interfaces, invocationHandler);


167. Как написать RMI клиент?

- получаем доступ к регистру удаленных объектов, вызывая метод getRegistry(), по


тому же порту, что прописывали в сервере.

final Registry registry = LocateRegistry.getRegistry(int portNumber);

- создаем ссылочную переменную с типом интерфейса (точно такого же как и у


сервера) и получаем прокси-объект.

registry.lookup(String name);

- удаленно вызываем нужные нам методы нашего прокси-объекта.

168. Как написать RMI сервер?

- создается экземпляр класса (наш объект).

- создается реестр удаленных объектов (сюда добавляются все объекты для


расшаривания) и прописывается порт.

final Registry registry = LocateRegistry.getRegistry(int portNumber);

- создается заглушка (объект, который содержит НАШ ОБЪЕКТ со всеми его


методами, полями. Заглушка принимает запрос от клиента, после чего отправляет ему
результат/исключение.

Remote obj = UnicastRemoteObject.exportObject(server, 0);

server - это экземпляр нашего класса, 0 - любой свободный порт.

- в реестр заносится уникальное имя и заглушка.

registry.bind(String name, Remote obj);

Дальше клиент работает только с реестром, в котором находятся наши заглушки (в


них же НАШИ ОБЪЕКТЫ) - вроде бы все понятно!

169. Как разрешить RMI-доступ из других компьютеров сети?

https://habr.com/ru/post/185710/
170. Распространённые RMI ошибки?

https://docs.oracle.com/javase/9/docs/specs/rmi/exceptions.html

171. Зачем нужен RandomAccessFile?

Данный класс поддерживает чтение файла и запись в файл в произвольном месте


благодаря специальному курсору, т.н. указателю файла. Можно менять позицию
курсора для текущей операции чтения/записи. Курсор сдвигается на указанный номер
байта. Благодаря RandomAccessFile возможно изменять фрагменты файла, а также
писать и читать файл одновременно.

172. Что будет если файл, откуда читает RandomAccessFile, не существует?

RandomAccessFile создаст пустой файл. Если создать файл не получится, то будет


выкинуто исключение FileNotFoundException.

173. Что будет если файл, куда пишет RandomAccessFile, не существует?

RandomAccessFile создаст пустой файл и запишет в него данные. Если создать файл
не получится, то будет выкинуто исключение FileNotFoundException.

174. Зачем нужен класс StringReader?

Для посимвольного чтения строки в поток.

175. Зачем нужен класс StringWriter?

Символьный поток, который собирает свои выходные данные в строковом буфере,


который затем может использоваться для создания строки. При записи в StringWriter
его внутренний буфер удлиняется.

176. Зачем нужен класс ByteArrayStream?

Класс ByteArrayInputStream представляет собой поток чтения байтов из массива


байтов.

Класс ByteArrayOutputStream представляет собой поток записи байтов во внутренний


массив байтов, способный динамически увеличиваться.

177. Зачем нужен класс PrintStream? Назовите места, где он используется?


Используется для вывода информации в консоль методами print(),printf() и println().
System.out – это статическая переменная класса System тип PrintStream.

Данный класс также можно использовать для записи информации в поток вывода.

178. Зачем нужен DynamicProxy?

Это паттерн, с помощью которого фактически можно сконструировать объект во время


исполнения программы (динамически), не создавая для него отдельного класса.
Обычно создание таких прокси используется для имитации объектов из программ,
которые физически запущены на другом компьютере. Или для контроля доступа – в
таком методе можно проверять права текущего пользователя, обрабатывать ошибки и
многое другое. Для создание DynamicProxy используется специальный класс
(java.lang.reflect.Proxy).

179. Как работает RMI?

Remote Method Invocation – это механизм, который позволяет объекту в одной Java-
машине вызывать методы объекта в другой Java-машине, даже если они находятся на
разных компьютерах.

Для вызова методов объекта на другом компьютер необходимо передать параметры


метода на другой компьютер, сообщить объекту о необходимости выполнения метода,
а затем получить обратно возвращаемое значение. Механизм RMI даёт возможность
организовать выполнение всех этих операций.

https://ru.wikipedia.org/wiki/RMI

180. Объекты каких типов можно передавать по RMI?

Параметры переданных в "заглушке" методов должны быть сериализуемыми.

181. Что такое JSON?

JSON (JavaScript Object Notation) — текстовый формат обмена данными между


сервером и программой , основанный на JavaScript. Применяется в веб-приложениях
как для обмена данными между браузером и сервером (AJAX), так и между серверами
(программные HTTP-сопряжения).

182. В чем связь JSON и JavaScript?

Формат JSON основан на языке JavaScript.

183. Как использовать Jackson?


Jackson - это библиотека фреймворков для сериализации объекта в JSON. Для
конвертации объекта в JSON и обратно используется класс ObjectMapper
(com.fasterxml.jackson.databind.ObjectMapper).

184. Java jackson. Как настроить сериализацию в JSON?

//Помечаем класс для сериализации в JSON нужной аннотацией

@JsonAutoDetect

class Cat

public String name;

public int age;

public int weight;

Cat(){}

public static void main(String[] args) throws IOException

//создаем объекта для сериализации в JSON

Cat cat = new Cat();

cat.name = "Murka";

cat.age = 5;

cat.weight = 4;

//писать результат сериализации будем во Writer(StringWriter)

StringWriter writer = new StringWriter();

//это объект Jackson, который выполняет сериализацию

ObjectMapper mapper = new ObjectMapper();


// сама сериализация: 1-куда, 2-что

mapper.writeValue(writer, cat);

//преобразовываем все записанное во StringWriter в строку

String result = writer.toString();

System.out.println(result);

Для десериализации в ObjectMapper передаем строку с JSON или StringReader, а


также класс объекта, который надо десериализовать. Вызываем метод readValue, и на
выходе получаем готовый Java-объект со всеми данными.

public static void main(String[] args) throws IOException

String jsonString = "{ \"name\":\"Murka\", \"age\":5, \"weight\":4}";

StringReader reader = new StringReader(jsonString);

ObjectMapper mapper = new ObjectMapper();

Cat cat = mapper.readValue(reader, Cat.class);

@JsonAutoDetect

class Cat {

public String name;

public int age;

public int weight;

Cat() {}

Требования к объектам, которые сериализуются/десериализуются в JSON:

1) поля должны быть видимые - public, либо иметь getter’ы и setter’ы;


2) должен быть конструктор по умолчанию (без параметров);

3) Нужно расставлять правильные аннотации.

185. Настройка JAXB?

JAXB – это многофункциональный фреймворк для работы с XML, который, как и JSON,
часто применяется при пересылке данных между разными программами и
компьютерами.

Нужно импортировать следующие библиотеки из папка с IDEA -> lib:

- jaxb-api

- jaxb-runtime

- javax.activation

186. Сериализация в JAXB?

/*Помечаем класс для сериализации в XML нужной аннотацией

* @XmlRootElement указывает на то, что этот объект может быть «корнем дерева»
элементов

* в XML. Т.е. быть элементом самого верхнего уровня, все остальные элементы лежат
в нем.

* @XmlType(name = «cat») указывает на то, что класс участвует в JAXB


сериализации, в ней

* же задано имя, которое будет у XML-тега для этого класса.

*/

@XmlType(name = "cat")

@XmlRootElement

class Cat{

public String name;

public int age;

public int weight;

Cat(){}

}
public static void main(String[] args) throws JAXBException

//создаем объект для сериализации в XML

Cat cat = new Cat();

cat.name = "Murka";

cat.age = 5;

cat.weight = 4;

//писать результат сериализации будем в Writer(StringWriter)

StringWriter writer = new StringWriter();

//создаем объект Marshaller, который выполняет сериализацию

JAXBContext context = JAXBContext.newInstance(Cat.class);

Marshaller marshaller = context.createMarshaller();

// устанавливает свойство FORMATTED_OUTPUT в TRUE.

// в результате будут добавлены переносы строк и пробелы

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

// сама сериализация

marshaller.marshal(cat, writer);

//преобразовываем в строку все записанное в StringWriter

String result = writer.toString();

System.out.println(result);

Вывод:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<cat>
<name>Murka</name>

<age>5</age>

<weight>4</weight>

</cat>

Конвертация объекта из XML:

- Задаем строку, которая хранит xml для десериализации.

- Оборачиваем xml-строку в StringReader.

- Создаем JAXB-контекст, куда передаем список классов.

- Создаем Unmarshaller – объект, который будет выполнять десериализацию.

- Десериализуем xml из объекта reader и получаем объект cat типа Cat.

public static void main(String[] args) throws JAXBException{

String xmldata = "<cat><name>Murka</name><age>5</age><weight>4</weight></cat>"";

StringReader reader = new StringReader(xmldata);

JAXBContext context = JAXBContext.newInstance(Cat.class);

Unmarshaller unmarshaller = context.createUnmarshaller();

Cat cat = (Cat) unmarshaller.unmarshal(reader);

@XmlType(name = "cat")

@XmlRootElement

class Cat{

public String name;

public int age;

public int weight;

Cat(){}

}
187. Аннотации в JAXB?

https://www.codeflow.site/ru/article/jaxb

https://docs.oracle.com/javaee/7/api/javax/xml/bind/annotation/package-summary.html

@XmlElement(name) Ставится около поля. Поле будет представлено


XML-элементом. Позволяет задать имя для тэга.

@XmlAttribute(name) Ставится около поля. Поле будет представлено


XML-атрибутом. Позволяет задать имя для
атрибута.

@XmlElementWrapper(nillable Ставится около поля.


= true)
Позволяет задать «обрамляющий тег» для группы
элементов.

@XmlType Ставится около класса.

Позволяет задать метод для создания объекта,


если конструктор по умолчанию private.

@XmlJavaTypeAdapter Ставится около поля.

Позволяет задать класс, который будет


преобразовывать данные поля в строку.

@XmlRootElement указывает на то, что этот объект может быть


«корнем дерева» элементов в XML. Т.е. быть
элементом самого верхнего уровня, все остальные
элементы лежат в нем.

188. Документация по Jackson?

https://fasterxml.github.io/jackson-databind/javadoc/2.4/
189. Документация по JAXB?

https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html

https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/package-frame.html

https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/package-frame.html

https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/util/package-frame.html

190. Проблемы десериализации в Jackson?

При сериализации в объект JSON jбъекты типов Array(массив), ArrayList, LinkedList и


др. заменяются на массив в JSON-формате. А при десериализации неясно, какой
объект создать — ArrayList, LinkedList или HashMap.

В этом случае можно оставить настройки Jackson по умолчанию (jackson сам


определяет классы, которые будут использоваться при десериализации) либо
воспользоваться аннотациями.

Конвертация объекта из JSON:

public class Solution {

public static void main(String[] args) throws IOException {

String jsonString = "{\"name\":\"Murka\", \"cats\":[{\"name\":\"Timka\"},


{\"name\":\"Killer\"}]}";

ObjectMapper mapper = new ObjectMapper();

Cat cat = mapper.readValue(jsonString, Cat.class);

System.out.println(cat);

System.out.println(cat.cats.getClass());

class Cat {

public String name;

@JsonDeserialize(as = LinkedList.class)

public List<Cat> cats;

}
Аннотация @JsonDeserialize(as = LinkedList.class) означает, какую реализацию
интерфейса List использовать. В случае, если тип данных в List тоже интерфейс, то в
аннотации также можно указать еще и тип параметр.

Тип коллекции List - @JsonDeserialize(contentAs=ValueTypeImpl.class)

Тип коллекции Map - @JsonDeserialize(keyAs=KeyTypeImpl.class)

В случае, когда надо десериализовать структуру данных, которая содержит классы


данных, унаследованные от одного базового класса или интерфейса, нужно:

- выделить некоторое поле, которое используется для того, чтобы отличать один тип
от другого. Если его нет – его заводят.

- нужно воспользоваться специальными аннотациями, которые позволяют управлять


процессом «полиморфной десериализации».

Конвертация объекта в JSON:

public static void main(String[] args) throws IOException {

Cat cat = new Cat();

cat.name = "Murka";

cat.age = 5;

Dog dog = new Dog();

dog.name = "Killer";

dog.age = 8;

dog.owner = "Bill Jeferson";

House house = new House();

house.pets.add(dog);

house.pets.add(cat);

StringWriter writer = new StringWriter();

ObjectMapper mapper = new ObjectMapper();

mapper.writeValue(writer, house);

System.out.println(writer.toString());

}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property="type")

@JsonSubTypes({

@JsonSubTypes.Type(value=Cat.class, name="cat"),

@JsonSubTypes.Type(value=Dog.class, name="dog")

})

class Pet {

public String name;

class Cat extends Pet {

public int age;

class Dog extends Pet {

public int age;

public String owner;

class House {

public List<Pet> pets = new ArrayList<>();

Вывод:

"pets" : [

{"type" : "dog","name" : "Killer", "age" : 8, "owner" : "Bill Jeferson"},

{"type" : "cat","name" : "Murka", "age" : 5}

]
}

С помощью аннотаций мы указываем, что JSON-представление будет содержать


специальное поле type, которое будет хранить значение cat для класса Cat и значение
dog для класса Dog. Этой информации достаточно, чтобы выполнить корректную
десериализацию объекта: при десериализации по значению поля type будет
определяться тип объекта, который надо создать.

191. В чем отличия Java и JavaScript?

Язык программирования JavaScript, разработанный в компании Netscape, Inc., не


входит в состав платформы Java.

JavaScript не применяется для создания апплетов или автономных приложений. Чаще


всего JavaScript находится внутри документов HTML и обеспечивает уровень
взаимодействия с веб-страницами, которого невозможно достичь с помощью простых
документов HTML.

Основные различия Java и JavaScript:

- Java представляет собой объектно-ориентированный язык программирования, а


JavaScript - это объектно-ориентированный язык создания сценариев.

- Java используется для создания приложений, которые запускаются на виртуальных


машинах или в браузерах, а код JavaScript выполняется только в браузере.

- Код Java необходимо скомпилировать, а код JavaScript используется в текстовом


виде.

- Для них требуются различные подключаемые модули.

192. В чем отличия JSON и XML?

XML - язык разметки, имеющий древовидную структуру, элементы которой обрамлены


открывающими и закрывающими тэгами.

JSON - текстовый формат обмена данными между сервером и программой ,


основанный на JavaScript, во множестве языках реализованный как массив данных.

Для работы с обоими стандартами используются различные фреймворки с различным


синтаксисом.

193. Какие фреймворки для работы с JSON вы знаете?

- Jackson

- Genson

- Gson
- LoganSquare (основан на Jackson's streaming API)

- Alibaba Fastjson

194. Какие фреймворки для работы с XML вы знаете?

Существуют следующие API для работы с XML:

- SAX

- DOM

- Stax

- JAXB

Также существует множество реализаций данных API.

http://www.edankert.com/jaxpimplementations.html

195. Какие аннотации Jackson вы знаете?

@JsonAutoDetect Ставится перед классом.

Помечает класс как готовый к сериализациив JSON.

@JsonIgnore Ставится перед свойством.

Свойство игнорируется при сериализации.

@JsonProperty Ставится перед свойством или getter’ом или setter’ом.


Позволяет задать другое имя поля при сериализации.

@JsonPropertyOrder Ставится перед классом.

Позволяет задать порядок полей для сериализации.

https://nsergey.com/jackson-annotations/
196. Какие аннотации JAXB вы знаете?

@XmlElement(name) Ставится около поля. Поле будет представлено


XML-элементом. Позволяет задать имя для тэга.

@XmlAttribute(name) Ставится около поля. Поле будет представлено


XML-атрибутом. Позволяет задать имя для
атрибута.

@XmlElementWrapper(nillable Ставится около поля.


= true)
Позволяет задать «обрамляющий тег» для группы
элементов.

@XmlType Ставится около класса.

Позволяет задать метод для создания объекта,


если конструктор по умолчанию private.

@XmlJavaTypeAdapter Ставится около поля.

Позволяет задать класс, который будет


преобразовывать данные поля в строку.

@XmlRootElement указывает на то, что этот объект может быть


«корнем дерева» элементов в XML. Т.е. быть
элементом самого верхнего уровня, все остальные
элементы лежат в нем.

https://www.codeflow.site/ru/article/jaxb

https://docs.oracle.com/javaee/7/api/javax/xml/bind/annotation/package-summary.html

197. В чем отличие сериализации и десериализации в JSON?

- если указан интерфейс, при десереализации требуется указать конкретную


реализацию;

- если десериализация может пройти не успешно, поэтому требуется указание


дополнительного идентификатора и сопоставление типу конкретного класса, который
будет использован при сериализации (в JSON появится доп. поле). На него же будет
ориентироваться десериализация.
198. Что лучше JSON или XML? Почему?

Json - для универсальных web-приложений, xml - для корпоративных. Например,


системы криптографии заточены именно под XML (зашифровывание отдельных
элементов XML и передача их на центральный сервер используя WSDL).

https://habr.com/ru/post/31225/

199. Что такое DTO?

DTO (Data Transfer Object) - объект, который создается с целью быть использованным
при транспортировке данных. Обычно к таким объектам два требования: а) уметь
хранить данные, б) уметь сериализоваться. Т.е. их используют только для пересылки
данных.Создал объект, записал в него нужные данные из бизнес-логики, сериализовал
в JSON/XML и отправил куда-надо. Или наоборот – пришло сообщение –
десериализовал его в DTO-объект и вытягивай из него данные."

200. Как работает сборщик мусора в Java?

Сборщик мусора — это низкоприоритетный фоновый процесс, который периодически


запускается и освобождает память, использованную объектами, которые больше не
нужны. Сборщик мусора работает в фоновом режиме, параллельно с программой, в
отдельном потоке.

Основа для сборки мусора не подсчет ссылок, а разделение объектов на два вида —
достижимые и недостижимые. Объект считается достижимым (живым), если на него
ссылается другой достижимый (живой) объект. Достижимость считается от нитей.
Работающие нити всегда считаются достижимыми (живыми), даже если на них никто
не ссылается.

Все объекты в Java хранятся в специальной области памяти, которая называется куча
(heap). Все объекты в программах можно разделить на два типа — условно говоря,
простые объекты и “долгожители”. “Долгожителями” считаются объекты, пережившие
много сборок мусора. Чаще всего они будут существовать до конца работы
программы. В итоге общая куча, где хранятся все созданные объекты, была разделена
на несколько частей.

Первая часть имеет красивое название — Eden (библ. “Райский сад”), куда объекты
попадают после их создания. Именно в этой части выделяется память для новых
объектов, когда мы пишем new. Объектов может создаться много, и когда в этой
области заканчивается место, начинается первая, “быстрая” сборка мусора. Надо
сказать, что сборщик мусора очень умен и выбирает алгоритм работы в зависимости
от того, чего в куче больше — мусора или рабочих объектов. Если почти все объекты
являются мусором, сборщик помечает “живые” объекты и переносит их в другую
область памяти, после чего текущая область очищается полностью. Если же мусора
мало и большую часть занимают живые объекты, он помечает мусор, очищает его, а
остальные объекты компонует.
Область памяти, куда переносятся все объекты, пережившие хотя бы одну сборку
мусора, называется Survival Space (“место для выживших”). Survival Space в свою
очередь делится на поколения. Каждый объект относится к своему поколению в
зависимости от того, сколько сборок мусора он пережил. Если одну — он относится к
“Поколению 1”, если 5 — к “Поколению 5”. Вместе Eden и Survival Space образуют
область под названием Young Generation (“молодое поколение”).

Помимо Young Generation в куче существует и другая область памяти — Old


Generation (“старое поколение”). Сюда как раз попадают те самые объекты-
долгожители, которые пережили много сборок мусора. Их выгоднее хранить отдельно
от всех остальных. И только когда область Old Generation заполнена, т.е. даже
объектов-долгожителей в программе так много, что памяти не хватает, производится
полная уборка мусора. Она обрабатывает не одну область памяти, а вообще все
созданные Java-машиной объекты. Естественно, она занимает куда больше времени и
ресурсов. Именно поэтому объекты-долгожители было решено хранить отдельно.
Когда место заканчивается в других областях, проводится так называемая “быстрая
сборка мусора”. Она охватывает только одну область, и за счет этого является более
экономичной и быстрой. В конце, когда забита уже даже область для долгожителей, в
бой вступает полная уборка. Таким образом, самый “тяжеловесный” инструмент
используется сборщиком только тогда, когда без этого уже не обойтись.

201. Какие бывают виды сборщиков мусора?

Serial Garbage Collector

Parallel Garbage Collector

CMS Garbage Collector

G1 Garbage Collector

Epsilon Garbage Collector

Z garbage collector

Shenandoah Garbage Collector

202. Что такое «поколения» объектов?

Все объекты в Survival Space делятся на поколения. Каждый объект относится к


своему поколению в зависимости от того, сколько сборок мусора он пережил. Если
одну — он относится к “Поколению 1”, если 5 — к “Поколению 5”.

203. Для чего используется SoftReference?

Объект, на который ссылаются только мягкие ссылки, может быть удален сборщиком
мусора, если программе не хватает памяти. Если программе вдруг не хватает памяти,
прежде чем выкинуть OutOfMemoryException, сборщик мусора удалит все объекты, на
которые ссылаются мягкие ссылки и попробует выделить программе память еще раз.
Объект, который удерживает от смерти только SoftReference может пережить сколько
угодно сборок мусора и скорее всего, будет уничтожен при нехватке программе
памяти.

204. Пример использования SoftReference?

SoftReference можно использовать для реализации кэширования и когда JVM


понадобится память она освободит ее за счет удаления таких объектов.

205. Пример использования WeakReference?

Если на объект остались только слабые ссылки, то этот объект является живым, но он
будет уничтожен при ближайшей сборке мусора.

WeakReference отлично подойдут для хранения метаданных (допинформация о


содержимом или объекте), например для хранения ссылки на ClassLoader. Если нет
классов для загрузки, то нет смысла хранить ссылку на ClassLoader. Слабая ссылка
делает ClassLoader доступным для удаления как только мы назначим ее вместо
крепкой ссылки (Strong reference).

206. Зачем нужен WeakHashMap?

WeakHashMap - это реализация HashMap, в которой ключи представляют собой


слабые ссылки. WeakHashMap ссылается на ключи не прямо, а через WeakReference.
Пока на объекты, которые хранятся в WeakHashMap в качестве ключей, есть обычные
(сильные или мягкие) ссылки, эти объекты будут существовать.

Когда объекты, используемые в качестве ключей, станут слабодостижимыми, они


уничтожатся при ближайшей сборке мусора. А значит, из WeakHashMap
автоматически удалятся и их значения.

В WeakHashMap очень удобно хранить дополнительную информацию к каким-то


объектам.

Во-первых, ее очень легко получить, если использовать сам объект в качестве ключа.

Во-вторых, если объект будет уничтожен, из HashMap исчезнет и он, и все


привязанные к нему данные.

Например в программе есть нить, которая отслеживает работу некоторых объектов-


заданий и пишет информацию о них в лог. Тогда эта нить может хранить
отслеживаемые объекты в таком WeakHashMap. Как только объекты станут не нужны,
сборщик мусора удалит их, автоматически удалятся и ссылки на них из WeakHashMap.

207. Что такое логгер?

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

Весь процесс логирования состоит из трех частей.

Первая часть – это сбор информации.

Вторая часть – это фильтрование собранной информации.

Третья часть – это запись отобранной информации.

208. Как настроить логгер?

- В pom.xml добавить зависимость.

- Добавить в resources файл log4j.properties.

Обычно настройки логгера log4j задаются в файле log4j.properties или log4j.xml. В этом
файле можно задать несколько appender’ов – объектов, в которые будут писаться
данные.

a. место, куда будет писаться информация (файл, консоль, база данных, сеть и
т.д.)

b. сообщения какого уровня будут записываться

c. вид записей в логе

d. для файлов можно указать: путь к файлу и каталогу, размер файлов,


количество файлов

e. указать для каждого отдельного пакета свой уровень сообщений, которые


будут писаться в лог

- Добавить в класс с бизнес-логикой private static final Logger logger =


Logger.getLogger(ххх.class);

209. Когда вызывается метод finalize?

Этот метод вызывается Java-машиной у объекта перед тем, как объект будет
уничтожен. Однако Java-машина сама решает – вызвать данный метод или нет. Чаще
всего объекты, созданные в методе и объявленные мусором после его завершения,
уничтожаются сразу же и без всяких вызовов метода finalize().

Можно вручную запустить вызовы этого метода у всех недостижимых объектов метод
ом System.runFinalization() или Runtime.getRuntime().runFinalization().

210. Что произойдет, если в методе finalize возникнет исключение?


Это исключение будет проигнорировано, и произойдёт выход из метода.

Во время старта JVM запускается поток finalizer, который работает в фоне. Этот поток
имеет метод runFinalizer, который игнорирует все исключения методов finalize
объектов перед сборкой мусора. То есть если во время выполнения метода finalize
возникнет исключительная ситуация, его выполнение будет остановлено и это никак
не скажется на работоспособности самого сборщика мусора (garbage collector).

211. Что такое PhantomReference?

Это самый слабый тип ссылок.

Если на объект остались только фантомные ссылки, то у него:

- вызывается метод finalize() (если он переопределен);

- если после работы finalize() ничего не изменилось и объект все еще может быть
удален, фантомная ссылка на объект помещается в специальную очередь —
ReferenceQueue. Если же метод finalize() не переопределён, то этот объект пропускает
текущую сборку мусора, и попадает в следующую.

Объект не удаляется из памяти до тех пор, пока его фантомная ссылка находится в
этой очереди. Он будет удален только после того, как у фантомной ссылки будет
вызван метод clear().

Также стоит отметить, что метод get() у призрачной ссылка всегда возвращает null (в
отличие от SoftReference и WeakReference ссылок, у которых он возвращает null,
только если объект уже уничтожен).

212. Зачем нужно передавать очередь в конструктор PhantomReference?

Для отслеживания того, что объект больше не нужен. Может быть использовано для
закрытия ресурсов, открытых данным объектом (например, удаление созданных
файлов).

213. Какие системы контроля версий вы знаете?

Git, (Subversion) SVN, Perforce (P4), Bazaar, Mercurial

214. Чем отличаются SVN и Git?

а) SVN — централизованная СКВ, а Git — распределённая СКВ. Соответственно, гит


хранит все файлы и всю историю на локальном диске, SVN — же на сервере.

б) Git хранит «слепки» файлов в сжатом виде (причём, если файл не менялся, то
хранится ссылка на него), а SVN хранит изменения файлов.
в) В Git коммит может иметь несколько родителей (разных веток) и несколько
потомков (разных веток), а в SVN — нет. Соответственно, в SVN — линейная история
коммитов, а в Git — нет.

г) В Git ветка — это просто указатель на какой-то коммит, в SVN — это полноценная
копия всего репозитория.

д) Git создают одну скрытую папку в корне проекта, в которой хранит всю свою
служебную информацию, а SVN в каждой папке проекта создаёт скрытую папку со
своей служебной информацией.

215. Что такое GitHub? У вас есть проекты на GitHub?

GitHub — веб-сервис для хостинга IT-проектов и их совместной разработки с


использованием системы контроля версий git, а также социальная сеть для
разработчиков. Пользователи могут создавать неограниченное число репозиториев,
для каждого из которых предоставляется вики, система отслеживания ошибок, есть
возможность проводить code review и т.п. Кроме Git, сервис поддерживает получение и
редактирование кода через SVN и Mercurial.

216. Зачем нужны системы контроля версий?

Система управления версиями нужна для облегчения работы с изменяющейся


информацией и позволяет:

- хранить несколько версий одного и того же документа, т. н. ветки, с общей историей


изменений до точки ветвления и с разными — после неё;

- при необходимости возвращаться к более ранним версиям документа;

- определять, кто и когда сделал то или иное изменение;

- вести журнал изменений, в который пользователи могут записывать пояснения о том,


что и почему они изменили в данной версии.

- контролировать права доступа пользователей, разрешая или запрещая чтение или


изменение данных, в зависимости от того, кто запрашивает это действие.

217. Что такое generic? Как они реализованы в Java?

Generics — это типы с параметром. С их помощью можно объявлять классы,


интерфейсы, конструкторы и методы, где тип данных указан в виде параметра. Так
как параметризированные типы стираются из программы после компиляции, то
обобщения сохраняют безопасность типов.

Пример:

class Account<T>{

private T id;
private int sum;

Account(T id, int sum){

this.id = id;

this.sum = sum;

public T getId() { return id; }

public int getSum() { return sum; }

public void setSum(int sum) { this.sum = sum; }

С помощью буквы T в определении класса class Account<T> мы указываем, что


данный тип T будет использоваться этим классом. Параметр T (может быть любая
буква) в угловых скобках называется универсальным параметром, так как вместо него
можно подставить любой тип. Во время создания экземпляра класса нужно вместо
<T> подставить определенный тип, так далее в классе объявляется переменная этого
типа, которой затем присваивается значение в конструкторе.

public class Program{

public static void main(String[] args) {

Account<String> acc1 = new Account<String>("2345", 5000);

String acc1Id = acc1.getId();

System.out.println(acc1Id);

Account<Integer> acc2 = new Account<Integer>(2345, 5000);

Integer acc2Id = acc2.getId();

System.out.println(acc2Id);

Создаем 2 объекта: в acc1 вместо универсального параметра подставляем String,


после чего данный объект сможет работать только с этим типом; в acc2 подставляем
Integer, после чего данный объект сможет работать только с Integer.

В качестве параметризированных типов можно использовать только объекты, а не


примитивные типы. Вместо примитивов нужно использовать классы-обертки.
Обобщенные интерфейсы:

interface Accountable<T>{

T getId();

int getSum();

void setSum(int sum);

Обощенные методы:

public static <T> void fill(List<T> list, T val) {

for (int i = 0; i < list.size(); i++)

list.set(i, val);

В данном случае метод принимает на вход 2 параметра: список объектов T и еще один
отдельный объект Т. За счет использования <T> и достигается типизация метода: мы
не можем передать туда список строк и число. Список строк и строку, список чисел и
число, список наших объектов Cat и еще один объект Cat — только так.

Обощенные конструкторы:

class Account{

private String id;

private int sum;

<T>Account(T id, int sum){

this.id = id.toString();

this.sum = sum;

В данном случае конструктор принимает параметр id, который представляет тип T. В


конструкторе его значение превращается в строку и сохраняется в локальную
переменную.

В именах переменных типа принято использовать заглавные буквы. Обычно для


коллекций используется буква E, буквами K и V — типы ключей и значение
(Key/Value), а буквой T (и при необходимости буквы S и U) — любой тип.
218. Что такое стирание типов?

Внутри класса не хранится информация о его типе-параметре. Это и называется


стиранием типов. Эта информация доступна только на этапе компиляции и становится
недоступной в runtime.

219. Расскажите про extends и super в Generic’ах?

Ключевые слова extends и super используются с wildcards (подстановочными знаками)


для ограничения типов-параметров по иерархии наследования.

Тип Upper Bounded Wildcards означает, что в конструкцию <? extends Someclass>
можно подставить объект класса Someclass и любых его потомков.

Тип Lower Bounded Wildcards означает, что в конструкцию <? super Someclass> можно
подставить объект класса Someclass и любых его родителей.

? означает любой объект, T означает только объект T.

220. Что такое wildcard?

Wildcard (подстановочные знаки) — это разновидность типа-параметра, в которой


используется конструкция <?>, где знак ? означает, что тип может быть любым
объектом. В сочетании с extends и super позволяет ограничивать типы объектов,
которые можно подставлять в конструкцию <>.

221. Как использовать wildcard?

<T extends SomeClass> работает ТОЛЬКО с объектами типа T, наследующихся от


SomeClass.

<? extends SomeClass> работает с ЛЮБЫМИ объектами, наследующихся от


SomeClass.

<? super SomeClass> работает с ЛЮБЫМИ объектами, являющимися родителями


SomeClass.

extends (Upper Bounded Wildcards) - ограничение сверху (берем только то, что ниже по
иерархии наследования).

super (Lower Bounded Wildcards)- ограничение снизу (берем только то, что выше по
иерархии наследования).

Конструкция <? extends SomeClass> нужна для того, чтобы забирать элементы.

А конструкция <? super SomeClass> нужна, чтобы их добавлять.

Если нужно использовать объект и для добавления, и для извлечения элементов, то


нельзя использовать wildcards.
222. В чем отличие ArrayList и ArrayList<?>

Запись вида ArrayList называется raw type ("сырой" тип, класс-дженерик, из которого
удалили его тип). Если присвоить данной ссылке new ArrayList<>(), то в него можно
добавлять любые элементы и объекты, в т.ч разнотипные.

Запись вида ArrayList<?> означает, что данный список может работать с любыми
элементами. Однако, если присвоить данной ссылке new ArrayList<>(), то в него
нельзя добавлять никакие элементы, кроме null. Но можно присвоить данной ссылке
ArrayList<>() с любым содержимым.

223. Что такое граф?

Граф — абстрактный математический объект, представляющий собой совокупность


множества объектов, называемых вершинами графа, и множества их парных связей,
называемых рёбрами графа, то есть соединениями между парами вершин. Например,
за множество вершин можно взять множество аэропортов, обслуживаемых некоторой
авиакомпанией, а за множество рёбер взять регулярные рейсы этой авиакомпании
между городами.

224. Что такое дерево из теории графов?

Дерево — это связный ациклический граф. Связность означает наличие маршрута


между любой парой вершин, ацикличность — отсутствие циклов. Отсюда, в частности,
следует, что число рёбер в дереве на единицу меньше числа вершин, а между
любыми парами вершин имеется один и только один путь.

225. Что такое бинарное дерево?

Иерархическая структура данных, в которой каждый узел имеет не более двух


потомков. Как правило, первый называется родительским узлом, а потомки
называются левым и правым наследниками.

226. Что такое красно-черное дерево?

Красно-чёрное дерево - один из видов самобалансирующихся двоичных деревьев


поиска, гарантирующих логарифмический рост высоты дерева от числа узлов и
позволяющее быстро выполнять основные операции дерева поиска: добавление,
удаление и поиск узла.

Красно-чёрное дерево должно удовлетворять следующим требованиям:

- корень дерева — чёрный;

- узел либо красный, либо чёрный;


- все листья дерева — чёрные;

- оба потомка красно узла - чёрные;

- всякий путь от данного узла до любого листового узла, являющегося его потомка,
содержит одинаковое количество чёрных узлов.

227. Что такое MVC?

Model-View-Controller (MVC, «Модель-Представление-Контроллер», «Модель-Вид-


Контроллер») — схема разделения данных приложения, пользовательского
интерфейса и управляющей логики на три отдельных компонента: модель,
представление и контроллер — таким образом, что модификация каждого компонента
может осуществляться независимо.

Модель предоставляет данные и методы работы с ними: запросы в базу данных,


проверка на корректность. Модель ничего не знает ни о Виде, ни о Контроллере,
просто предоставляя доступ к данным и управлению ими, что делает возможным ее
разработку и тестирование как независимого компонента. И это является главным
моментом MVC.

Вид отвечает за отображение данных модели пользователю, реагируя на изменения


модели. Вид отображает Модель и получает из нее нужные для отображения данные
следующими способами:

- Активный Вид, который знает о Модели и сам берет из нее нужные данные.

- Пассивный Вид, которому данные поставляет Контроллер. В этом случае Вид с


Моделью никак не связан.

Контроллер интерпретирует действия пользователя, оповещая модель о


необходимости изменений. Контроллер всегда знает о Модели и может ее изменять
(как правило в результате действий пользователя).

228. Что такое EJB?

EJB (Enterprise Java Beans) – это фреймворк для построение бизнес-логики


приложения.

Сервер приложений J2EE (Jakarta EE) состоит из двух основных элементов:

- WEB-Container – (JSP, JSF и т.д.) все что дает конечный вид пользователю, а точней
пользовательский интерфейс.

- EJB-Container – используется для написания бизнес-логики.

EJB – это технология, предоставляющая множество готовых решений (управление


транзакциями, безопасность, хранение информации и т.п.) для приложения.

EJB делится на 3 компонента:


- Session beans – используется для построения бизнес-логики, которая может быть
вызвана программным клиентом через локальный, удаленный или веб-интерфейс
обслуживания клиентов. Для доступа к приложению, развернутого на сервере, клиент
вызывает методы сессионного компонента. Сессионный компонент выполняет работу
для своего клиента, защищая его от сложности, выполняя бизнес-задачи внутри
сервера.

Существует 2 типа session-beans: stateless и stateful. Stateful – автоматически


сохраняют свое состояние между разными клиентскими вызовами. Stateless –
используются для реализации бизнесс-процессов, которые могут быть завершены за
одну операцию.

- Message-Driven beans – компонент является корпоративным компонентом, который


позволяет Java EE приложениям обрабатывать сообщения асинхронно.

Этот тип бинов обычно действует в качестве слушателя JMS-сообщения, который


похож на слушателя событий, но получает JMS-сообщений вместо событий.
Сообщения могут быть отправлены на любой компонент Java EE (клиентское
приложение, другой компонент, или веб-компонент) или JMS приложение или систему,
которая не использует Java EE технологий. Message-Driven beans может обрабатывать
не только JMS сообщения, но и другие видов сообщений.

- Entities – это объекты EJB для хранения данных на период жизненного цикла Entity.
Entities является своего рода отображением таблиц в БД.

Одним из главным достоинством EJB3 стал новый механизм работы с persistence, он


дает возможность автоматически сохранять объекты в реляционной БД используя
технологию ORM. Являются частью JPA (Java Persistence API).

229. Что такое DAO и DTO?

DAO (data access object) — это объект для работы с БД или другим объектом хранения
данных, основная задача которого сохранять данные в базу данные, а также извлекать
их из неё.

DTO (Data Transfer Object) - это объект, предназначенный для передачи данных между
различными приложениями, либо между слоями внутри одного приложения. Он
должен уметь хранить данные и быть сериализуемым.

230. Устаревшие коллекции в java?

- интерфейс Enumeration – определяет методы, с помощью которых можно


перечислить (получить по одному) элементы в коллекции объектов. Был заменен
интерфейсом Iterator.
- класс Vector реализует динамический массив. В отличие от ArrayList , Vector
синхронизирован и содержит много устаревших методов, которые не являются частью
структуры коллекций.

- Stack — класс, наследуемый от Vector и реализующий механизм типа "последний


вошёл - первый вышел" (LIFO). Помимо унаследованных от Vector методов
определяет еще несколько:

empty(), peek(), pop(), push(Object element), search(Object element)

- Dictionary — аналог интерфейса Map, хотя представляет собой абстрактный класс, а


не интерфейс.

- Hashtable — аналог HashMap.

Все методы Hashtable, Stack, Vector являются синхронизированными, что делает их


менее эффективными в одно поточных приложениях.

231. Чем отличается TreeMap и HashMap?

TreeMap реализует интерфейсы NavigableMap и SortedMap, за счет чего получает


дополнительный функционал, которого нет в HashMap. Он хранит элементы
отсортированными в порядке возрастания или исходя из заданного компаратора.
Поэтому время доступа к элементам в TreeMap будем больше, чем в HashMap.
Операции add() , remove() и contains() в HashMap обеспечивают бОльшую
производительность, чем в TreeMap.

В HashMap же элементы хранятся в случайном порядке, который может изменяться


на протяжении времени.

TreeMap в своей структуре использует красно-чёрное дерево, а HashMap - элементы


Bucket (корзины), которые используются для хранения узлов (Nodes).

HashMap может хранить null в качестве ключа, а TreeMap не может.

*****

Элементы хранятся внутри HashMap в виде набора групп – корзин (bucket). В какую
корзину попадет элемент — зависит от значения его hashCode(). Смысл такого
хранения в том, что при поиске/удалении можно отбрасывать ненужные корзины, и
исключать все их элементы из рассмотрения.

Каждая корзина ссылается на связный список. А в каждом списке хранятся объекты


вложенного статического класса Node. Каждый элемент Node содержит ключ,
значение и ссылку на следующий элемент списка. То есть именно в нодах хранятся
все ключи и значения HashMap. Node реализует интерфейс Map.Entry, и сделано это
для универсальности, чтобы с разными реализациями map можно было
взаимодействовать одним способом. В Java 8 реализацию HashMap изменили, и
теперь, когда она вырастает до определённого размера, то меняет свою структуру на
дерево. Однако, для небольших размеров, все что написано выше, справедливо и
сейчас.
232. Чем отличается TreeSet и HashSet?

TreeSet использует в своей реализации TreeMap, а HashSet - HashMap. Поэтому их


отличия идентичны отличиям TreeMap и HashMap.

233. Что такое POJO?

POJO (Plain Old Java Object) - "старый добрый Java объект", простой Java-объект, не
унаследованный от какого-то специфического объекта и не реализующий никаких
служебных интерфейсов сверх тех, которые нужны для бизнес-модели.

Термин был придуман в пику EJB (Enterprise JavaBeans), так как отсутствие звучного
термина для простых объектов приводило к тому, что молодые Java-программисты
пренебрежительно к ним относились, считая что только EJB «спасут мир». Концепция
POJO появилась как результат поиска путей облегчения и упрощения методов
программирования для задач, требовавших от бизнес-объектов разносторонней
функциональности, включая хранение объектов в базе данных, веб-интерфейс и т.п.

234. Что такое Entity?

Это объект EJB для хранения данных на период жизненного цикла Entity. Является
своего рода отображением таблиц в БД.

235. Какие коллекции-списки вы знаете?

Все списки реализуют интерфейс List<E> и наследуются от абстрактного класса


AbstractList<E>.

- ArrayList<E> — это список, основанный на массиве;

- LinkedList<E> — двусвязный список.

- AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList ...

236. Какие коллекции-множества вы знаете?

Множества в Java реализуют интерфейс Set<E> и наследуются от AbstractSet<E> и


представляют собой набор уникальных элементов.

Множества:

- HashSet представляет собой множество, в котором элементы хранятся в случайном


порядке, который может изменяться на протяжении времени. Использует в своей
реализации HashMap.

- LinkedHashSet - множество, в котором элементы хранятся в порядке их добавления.


- TreeSet - множество, в котором элементы хранятся отсортированными в порядке
возрастания или исходя из заданного компаратора. Использует в своей реализации
TreeMap.

237. Что такое map, чем он отличается от «словаря»?

Map (словарь, карта, отображение) — это структура данных, представляющая собой


набор пар ключ-значение. При этом ключ в пределах словаря уникален.

В Java словарь, реализован классами HashMap, TreeMap, Hashtable, LinkedHashMap.

238. Что такое Queue и Dequeue?

Это специальные интерфейсы "очередей" - структуры данных, работающую по


принципу FIFO (first in - first out).

- Queue стандартная модель однонаправленной очереди, в которой, чем раньше был


добавлен элемент в коллекцию, тем раньше он из нее удаляется.

- Deque расширяет вышеописанный интерфейс Queue и определяет поведение


двунаправленной очереди, которая работает как обычная однонаправленная очередь,
либо как стек, действующий по принципу LIFO (last in - first out). В данной очереди мы
можем добавить элемент не только в начало, но и в конец. И соответственно удалить
элемент не только из конца, но и из начала.

239. Какие классы, реализующие интерфейс Queue вы знаете?

ArrayDeque, DelayQueue, LinkedList , PriorityQueue ...

240. Что такое дерево?

Дерево - это связный ациклический граф. При этом обычно одну вершину выбирают
корнем дерева, а остальные объявляют ее ветвями. Ветви дерева, которые не имеют
своих ветвей, называют листьями.

Дерево может быть:

- бинарным, если у каждого элемента дерева два потомка.

- полным бинарным деревом, если у каждой ветви 2 потомка, а все листья (без
потомков) находятся в одном ряду.

- красно-черным - бинарное самобалансирующееся дерево, элементы которого имеют


2 цвета: красный и черный.

241. Что такое паттерн проектирования?


Это шаблон проектирования, описывающий часто встречающееся решение
определённой проблемы при проектировании архитектуры программ.

Паттерн представляет собой не какой-то конкретный код, а общую концепцию решения


той или иной проблемы, которую нужно подстроить под нужды программы.

242. Какие паттерны проектирования вы знаете?

Singleton, Factory, Abstract Factory, Template method, Strategy, Pool, Adapter, Proxy,
Bridge, MVC

243. Расскажите про паттерн Singleton? Как сделать его потокобезопасным?

Паттерн Singleton гарантирует, что у класса есть только один экземпляр, и


предоставляет к нему глобальную точку доступа.

Область применения:

- В системе должно существовать не более одного экземпляра заданного класса.

- Экземпляр должен быть легко доступен для всех клиентов данного класса.

- Создание объекта on demand, то есть, когда он понадобится первый раз, а не во


время инициализации системы.

Вариант первый – самый простой. Однако у него есть единственный недостаток – он


не работает в многопоточной среде и поэтому не подходит в большинстве случаев.
Решение подходит исключительно для однопоточных приложений.

public class Singleton {

private static Singleton instance;

private Singleton() {}

public static Singleton getInstance() {

if (instance == null)

instance = new Singleton();

return instance;

}
Вариант второй, с синхронизацией, но использование volatile модификатора может
привести к проблемам производительности на мультипроцессорных системах.

public class Singleton {

private static volatile Singleton instance;

private Singleton() {}

public static Singleton getInstance() {

if (instance == null) {

synchronized (Singleton.class) {

if (instance == null) {

instance = new Singleton();

return instance;

https://javarush.ru/groups/posts/2365-patternih-proektirovanija-singleton

https://habr.com/ru/post/27108/

244. Расскажите про паттерн Factory

Фабричный метод - порождающий шаблон проектирования, предоставляющий


подклассам (дочерним классам) интерфейс для создания экземпляров некоторого
класса. В момент создания наследники могут определить, какой класс создавать.
Иными словами, данный шаблон делегирует создание объектов наследникам
родительского класса. Это позволяет использовать в коде программы не
специфические классы, а манипулировать абстрактными объектами на более высоком
уровне.

Пример: Класс AbstractWriter будет представлять абстракцию для записи в некоторый


контекст (будь то XML-документ или текстовый файл).
public abstract class AbstractWriter {

public abstract void write(Object context);

У этого класса может быть любое кол-во наследников. Рассмотрим подклассы


ConcreteFileWriter и ConcreteXmlWriter для записи в текстовый файл и DOM документ
соответственно:

public class ConcreteFileWriter extends AbstractWriter {

public void write (Object context) {

// method body

public class ConcreteXmlWriter extends AbstractWriter {

public void write (Object context) {

// method body

Для создания нужного нам объекта можно написать следующую Фабрику:

public class FactoryMethod {

public AbstractWriter getWriter(Object object) {

AbstractWriter writer = null;

if (object instanceof File) {

writer = new ConcreteFileWriter();

} else if (object instanceof Document) {

writer = new ConcreteXmlWriter();

return writer;

}
При создании объекта нужно передать в метод getWriter в качестве аргумента объект
File или DOM документ. В результате выполнения метода мы получим нужный объект
необходимого уровня абстракции.

Паттерн Factory используется в следующих случаях:

- класс не имеет информации о том, какой тип объекта он должен создать;

- класс передает ответственность по созданию объектов наследникам;

- необходимо создать объект в зависимости от входящих данных.

https://javarush.ru/groups/posts/2370-pattern-proektirovanija-factory

http://www.javenue.info/post/17

245. Расскажите про паттерн AbstractFactory

Абстрактная фабрика - порождающий шаблон проектирования, предоставляющий


интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов,
не специфицируя их конкретных классов. Шаблон реализуется созданием
абстрактного класса Factory, который представляет собой интерфейс для создания
компонентов. Затем пишутся классы, реализующие этот интерфейс.

Например, создадим холдинг по производству автомобилей. В нашей программе


Абстрактная фабрика (холдинг) будет представлена интерфейсом или абстрактным
классом. Предприятия, входящие в холдинг, представлены классами, реализующими
данный интерфейс.

//Производим только седаны и купе

interface Sedan {}

interface Coupe {}

interface CarsFactory {

Sedan createSedan();

Coupe createCoupe();

// Реализуем конкретное воплощение в виде автомобилей, создаваемых на той или иной фабрике

class ToyotaCoupe implements Coupe {

public ToyotaCoupe() {
System.out.println("Create ToyotaCoupe");

class ToyotaSedan implements Sedan {

public ToyotaSedan() {

System.out.println("Create ToyotaSedan");

class FordCoupe implements Coupe {

public FordCoupe () {

System.out.println("Create FordCoupe");

class FordSedan implements Sedan {

public FordSedan() {

System.out.println("Create FordSedan");

// в дочерних классах интерфейса CarsFactory реализуем его методы типом


возвращаемого //значения в методах будет являться именно общий для
возвращаемых значений тип – sedan и //coupe. Возвращаясь к нашей аналогии —
сказали фабрике сделать седан – сделали седан. //Особенности седана марки Ford
нас не интересуют.

class ToyotaFactory implements CarsFactory {

@Override

public Sedan createSedan() {

return new ToyotaSedan();


}

@Override

public Coupe createCoupe() {

return new ToyotaCoupe();

class FordFactory implements CarsFactory {

@Override

public Sedan createSedan() {

return new FordSedan();

@Override

public Coupe createCoupe() {

return new FordCoupe();

public class Main {

public static void main(String[] args) {

//создаем седан Тойота

CarsFactory factory = new ToyotaFactory();


factory.createSedan();

Вывод:

Create ToyotaSedan

https://javarush.ru/groups/posts/2379-patternih-proektirovanija-abstractfactory

246. Расскажите про паттерн Adaper, его отличия от Wrapper?

Адаптер - структурный шаблон проектирования, предназначенный для организации


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

Класс Adapter приводит интерфейс класса Adaptee в соответствие с интерфейсом


класса Target (который реализуется классом Adapter). Это позволяет объекту Client
использовать объект Adaptee (посредством адаптера Adapter) так, словно он является
экземпляром класса Target. Таким образом Client обращается к интерфейсу Target,
реализованному классом Adapter, который перенаправляет обращение к Adaptee.

Вариант через композицию

// Файл Chief.java

public interface Chief {

public Object makeBreakfast();

public Object makeDinner();

public Object makeSupper();

// Файл Plumber.java

public class Plumber {


public Object getPipe() {

return new Object();

public Object getKey() {

return new Object();

public Object getScrewDriver() {

return new Object();

// Файл ChiefAdapter.java

public class ChiefAdapter implements Chief {

private Plumber plumber = new Plumber();

@Override

public Object makeBreakfast() {

return plumber.getKey();

@Override

public Object makeDinner() {

return plumber.getScrewDriver();

}
@Override

public Object makeSupper() {

return plumber.getPipe();

// Файл Client.java

public class Client {

public static void main(String [] args) {

Chief chief = new ChiefAdapter();

Object key = chief.makeDinner();

В варианте через наследование нужно прописать адаптер следующим образом:

public class ChiefAdapter extends Plumber implements Chief

https://ru.wikipedia.org/wiki/Адаптер_(шаблон_проектирования)

http://www.javenue.info/post/63

https://javarush.ru/groups/posts/2361-kakie-zadachi-reshaet-shablon-proektirovanija-adapter

247. Расскажите про паттерн Proxy

Заместитель — структурный шаблон проектирования, предоставляющий объект,


который контролирует доступ к другому объекту, перехватывая все вызовы
(выполняет функцию контейнера).
Чтобы внедрить этот паттерн, нужно создать класс-прокси. Он реализует интерфейс
сервисного класса, имитируя его поведение для клиентского кода. Таким образом
вместо реального объекта клиент взаимодействует с его заместителем. Как правило,
все запросы передаются далее сервисному классу, но с дополнительными действиями
до или после его вызова. Проще говоря, этот прокси-объект — прослойка между
клиентским кодом и целевым объектом.

Рассмотрим пример с кэшированием запроса из очень медленного старого диска.


Пусть это будет расписание электропоездов в каком-нибудь древнем приложении, чей
принцип действия нельзя изменять. Диск с обновленным расписанием вставляют
каждый день в фиксированное время. Итак, у нас есть:

Интерфейс TimetableTrains.

Класс TimetableElectricTrains, который реализует этот интерфейс. Именно через этот


класс клиентский код взаимодействует с файловой системой диска.

Класс-клиент DisplayTimetable. Его метод printTimetable() использует методы класса


TimetableElectricTrains.

При каждом вызове метода printTimetable() класс TimetableElectricTrains обращается


на диск, выгружает данные и предоставляет их клиенту. Эта система функционирует
хорошо, но очень медленно. Поэтому было решено увеличить производительность
системы, добавив механизм кэширования. Новая реализация загружает расписание
один раз в день, а при повторных запросах возвращает уже загруженный объект из
памяти.

interface TimetableTrains {

String[] getTimetable();

String getTrainDepartureTime(String trainId);

//Чтобы каждый раз не читать файл с диска при попытке получить расписание всех
поездов мы //создаем класс-заместитель, который кэширует данные при первом
обращении к файлу.

class TimetableElectricTrainsProxy implements TimetableTrains {

// Ссылка на оригинальный объект

private TimetableTrains timetableTrains = new TimetableElectricTrains();

private String[] timetableCache = null;

@Override
public String[] getTimetable() {

if(timetableCache == null) {

timetableCache = timetableTrains.getTimetable();

return timetableCache;

@Override

public String getTrainDepartureTime(String trainId) {

if(timetableCache == null) {

timetableCache = timetableTrains.getTimetable();

for(int i = 0; i < timetableCache.length; i++) {

if(timetableCache[i].startsWith(trainId+";")) return timetableCache[i];

return "";

public void clearCache() {

timetableTrains = null;

//Класс, реализующий основной интерфейс:

class TimetableElectricTrains implements TimetableTrains {

//имитируем загрузку данных из файла

@Override
public String[] getTimetable() {

return new String[]{

"9B-6854;Лондон;Прага;13:43;21:15;07:32",

"BA-1404;Париж;Грац;14:25;21:25;07:00",

"9B-8710;Прага;Вена;04:48;08:49;04:01",

"9B-8122;Прага;Грац;04:48;08:49;04:01"

};

@Override

public String getTrainDepartureTime(String trainId) {

String[] timetable = getTimetable();

for(int i = 0; i<timetable.length; i++) {

if(timetable[i].startsWith(trainId+";")) return timetable[i];

return "";

class DisplayTimetable {

// Заменить в клиентском коде создание оригинального объекта на объект-заместитель

private TimetableTrains timetableTrains = new TimetableElectricTrainsProxy();

public void printTimetable() {

String[] timetable = timetableTrains.getTimetable();

String[] tmpArr;

System.out.println("Поезд\tОткуда\tКуда\t\tВремя отправления\tВремя
прибытия\tВремя в пути");
for(int i = 0; i<timetable.length; i++) {

tmpArr = timetable[i].split(";");

System.out.printf("%s\t%s\t%s\t\t%s\t\t\t\t%s\t\t\t%s\n", tmpArr[0], tmpArr[1],


tmpArr[2], tmpArr[3], tmpArr[4], tmpArr[5]);

Преимущества:

+ Можно как угодно контролировать доступ к сервисному объекту;

+ Дополнительные возможности управления жизненным циклом сервисного объекта;

+ Работает без сервисного объекта;

+ Повышает быстродействие и безопасность кода.

Недостатки:

- Есть риск ухудшения производительности из-за дополнительных обработок;

- Усложняет структуру классов программы.

248. Что такое итератор? Какие интерфейсы, связанные с итератором, вы знаете?

Итератор — это специальный внутренний объект коллекции, который позволяет


последовательно перебирать элементы этой коллекций. Этот объект должен
реализовывать интерфейс Iterator<E>, либо ListIterator<E> (для списков). Также, для
того, чтобы перебирать элементы коллекции, коллекция должна поддерживать
интерфейс Iterable<E>. Интерфейс Iterable<E> содержит всего один метод — iterator(),
который позволяет извне получить доступ к итератору коллекции.

Интерфейс Iterator<E> содержит методы:

boolean hasNext() — проверяет, есть ли в коллекции ещё какой-то элемент

E next() — позволяет получить очередной элемент коллекции (после получения


элемента, внутренний курсор итератора передвигается на следующий элемент
коллекции)

void remove() — удаляет текущий элемент из коллекции

Интерфейс же ListIterator<E> содержит методы:

boolean hasNext() — проверяет, существуют ли ещё один элемент в коллекции


(следующий за текущим)
E next() — возвращает очередной элемент коллекции (и передвигает внутренний
курсок итератора на следующий элемент)

int nextIndex() — возвращает индекс следующего элемента

void set(E e) — устанавливает значение текущего элемента void add(E e).


Добавляет элемент в конец списка.

boolean hasPrevious() — проверяет, существует ли какой-то элемент в коллекции


перед данным элементом

E previous() — возвращает текущий элемент коллекции и переводит курсор на


предыдущий элемент коллекции

int previousIndex — возвращает индекс предыдущего элемента коллекции

void remove() — удаляет текущий элемент коллекции

void add(E e) — добавляет элемент e после текущего элемента коллекции

249. Зачем нужен класс Arrays?

Класс Arrays — это утилитарный класс java.util.Arrays, предназначенный для


разнообразных манипуляций с массивами. В этом классе есть методы превращения
массива в список, поиска по массиву, копирования массива, сравнения массивов,
получения хешкода массива, представление массива в виде строки и др.

250. Зачем нужен класс Collections?

Класс Collections — это утилитарный класс java.util.Collections для работы с


коллекциями. В этом классе есть методы добавления элементов в коллекцию,
наполнения коллекции элементами, поиска по коллекции, копировании коллекции,
сравнения коллекции, нахождения максимального и минимального элементов
коллекции, а также методы получения специфический модификаций коллекций
известных типов (например, можно получить потокобезопасную коллекции или
неизменяемую коллекцию с одним элементом).

251. Что такое Agile?

Agile — это серия подходов к гибкой разработке программного обеспечения,


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

-люди и взаимодействие важнее процессов и инструментов;

-работающий продукт важнее исчерпывающей документации;

-сотрудничество с заказчиком важнее согласования условий контракта;

-готовность к изменениям важнее следования первоначальному плану.

Основополагающие принципы такого подхода:

-наивысшим приоритетом признается удовлетворение заказчика за счёт ранней и


бесперебойной поставки ценного программного обеспечения;

-изменение требований приветствуется даже в конце разработки (это может повысить


конкурентоспособность полученного продукта);

-частая поставка работающего программного обеспечения (каждые пару недель или


пару месяцев с предпочтением меньшего периода);

-общение представителей бизнеса с разработчиками должно быть ежедневным на


протяжении всего проекта;

-проекты следует строить вокруг заинтересованных людей, которых следует


обеспечить нужными условиями работы, поддержкой и доверием;

-самый эффективный метод обмена информацией в команде — личная встреча;

-работающее программное обеспечение — лучший измеритель прогресса;

-спонсоры, разработчики и пользователи должны иметь возможность поддерживать


постоянный темп на неопределённый срок;

-постоянное внимание к техническому совершенству и хорошему проектированию


увеличивают гибкость;

-простота как искусство не делать лишней работы очень важна;

-лучшие требования, архитектура и проектные решения получаются у


самоорганизующихся команд;

-команда регулярно обдумывает способы повышения своей эффективности и


соответственно корректирует рабочий процесс.

Основной проблемой разработки было признано то, что никто из участников ни на


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

252. Что такое Scrum?


Scrum — это одна из методик гибкой разработки. Она делает акцент на качественном
контроле процесса разработки. Основная особенность скрама — это разбиение
процесса разработки на итерации имеющий чёткую протяженность по времени
(обычно 2-6 недель; их называют "спринтами").

В начале спринта проводится "планирование спринта" — совещание на 3-4 часа, где


обсуждаются основные задачи, которые будут решаться на протяжении спринта. В
конце спринта проводится "демо" – демонтрация результатов работы команды за этот
спринт.

Перед самым первым спринтом заказчик (или его представитель) формирует список
требований, предъявляемых к будущему продукту. Такие требования называются
"user story", а самого заказчика называют "product owner". Также в этом списке
заказчик (PO) указывает приоритет для каждой задачи. Сначала будут
реализовываться задачи с более высоким приоритетом. Весь список называется
"product backlog", или "резерв продукта".

Кроме product owner, среди участников ещё выделяют scrum-мастера: он проводит все
совещания, следит за соблюдением всех принципов скрама, разрешает противоречия
и защищает команду от отвлекающих факторов. Обычно в качестве скрам-мастера
выступает кто-то из команды.

253. Какие роли Scrum вы знаете?

В скрам участников делят на "свиней" и "кур". "Свиньи" полностью задействованы в


процессе, "куры" — только частично.

К категории "свиней" относят следующие роли:

- Скрам-мастер (проводит совещания, следит за выполнением принципов скрама и пр.


Это кто-то из команды. Product owner не может быть скрам-мастером);

- Владетелей продукта (Product Owner) (представляет интересы конечных


пользователей и других заинтересованных в продукте сторон);

- Команда разработки (Development Team) (кросс-функциональная команда,


состоящая из специалистов разных профилей: разработчиков, тестировщиков,
дизайнеров, архитекторов и т.д. Размер команды в идеале составляет от 3 до 9
человек. Команда является единственные полностью вовлечённым участником
разработки и отвечает за результат как единое целое. Никто, кроме команды, не
может вмешиваться в процесс разработки на протяжении спринта).

К "курам" относятся следующие роли:

- Пользователи (Users)

- Клиенты, продавцы (Stakeholders) (лица, которые инициируют проект и для кого


проект будет приносить выгоду. Они вовлечены в скрам только во время обзорного
совещания по спринту (Sprint Review));

- Управляющие (Managers) (люди, которые управляют персоналом);

- Эксперты-консультанты (Consulting Experts).


254. Что такое спринт? Расскажите с подробностями

Спринт — это одна итерация цикла разработки программного обеспечения в Scrum.


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

255. Кто такие QA?

Quality Assuarance (тестировщики) - это специалисты, которые выявляют в программе


ошибки. Для этого они используют разные средства, как ручные, так и
автоматизированные. После выявления багов и ошибок они сообщают об этом
разработчикам, и те исправляют эти ошибки.

256. Кто такой product owner?

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

257. Расскажите об иерархии исключений

Исключения делятся на несколько классов, но все они имеют общего предка — класс
Throwable. Его потомками являются подклассы Exception и Error.

Исключения (Exceptions) являются результатом проблем в программе, которые в


принципе решаемые и предсказуемые. Например, произошло деление на ноль в
целых числах.

Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно


спецификации Java, не следует пытаться обрабатывать в собственной программе,
поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода
возникают, если закончилась память, доступная виртуальной машине. Программа
дополнительную память всё равно не сможет обеспечить для JVM.

В Java все исключения делятся на два типа: контролируемые исключения (checked) и


неконтролируемые исключения (unchecked), к которым относятся ошибки (Errors) и
исключения времени выполнения (RuntimeExceptions, потомок класса Exception).
Контролируемые исключения представляют собой ошибки, которые можно и нужно
обрабатывать в программе, к этому типу относятся все потомки класса Exception (но
не RuntimeException).

258. Что делать если JVM выкинула Error?

Программа завершится, т.к. это критическая ошибка, не всегда возникающая по вине


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

Первый тип ошибок возникает при переполнении стека вызовов — то есть, когда
вызывается слишком много методов и стек вызовов становится слишком большим
(бесконечная рекурсия или рекурсия с большим количеством итераций).

Вторая ошибка — OutOfMemoryError — возникает, когда переполняется память,


отведённая под объекты.

259. Какие нововведения в области исключений из Java 7 вы знаете?

- Multicatching: в одном catch-блоке сразу обрабатывается несколько исключений:

try {} catch (Exception1|Exception2|Exception3| ... | Exception e) {}

В таком случае параметр e будет неявно иметь модификатор final. Кроме того, байт-
код, сгенерированный компиляцией такого кода (с единым catch-блоком) будет короче,
чем байт-код, сгенерированный компиляцией кода с несколькими catch-блоками.

- Try-with-resources - конструкция, позволяющая после слова try в скобках указать


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

260. Зачем нужны аннотации? Как ими пользоваться?

Аннотация — специальная форма синтаксических метаданных, которая может быть


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

Выглядит как @ИмяАннотации, предваряющее определение переменной, параметра,


метода, класса, пакета.
Аннотация выполняет следующие функции:

- даёт необходимую информацию для компилятора / интерпретатора;

- даёт информацию различным инструментам для генерации другого кода и


конфигураций;

- может использоваться во время выполнения для получения данных через reflection;

Объявление аннотации идентично объявлению интерфейса.

@interface CatManager

Class manager();

boolean unique();

String name() default "Unknown Cat";

Перед словом interface ставится символ «@».

Аннотация может содержать значения по умолчанию. Для этого используется слово


default. Такие параметры являются необязательными и их можно опускать при
добавлении аннотаций.

Аннотации, используемые компилятором:

@Override — аннотация-маркер, которая может применяться только к методам. Метод,


аннотированный как @Override, должен переопределять метод супер класса.
@Override — проверяет, переопределён ли метод. Вызывает ошибку компиляции /
интерпретации, если метод не найден в родительском классе или интерфейсе;

@Deprecated — отмечает, что метод устарел и не рекомендуется к использованию.


Предполагается, что по каким-то причинам этот метод пока оставлен, но будет удалён
в будущих версиях. Вызывает предупреждение компиляции, если метод используется;

@SuppressWarnings — указывает компилятору подавить предупреждения компиляции,


определённые в параметрах аннотации;

@SafeVarargs — указывает, что никакие небезопасные действия, связанные с


параметром переменного количества аргументов, недопустимы. Применяется только к
методам и конструкторам с переменным количеством аргументов, которые объявлены
как static или final.
Аннотации, применяемые к другим аннотациям:

@Retention — определяет, как отмеченная аннотация может храниться — в коде, в


скомпилированном классе или во время работы кода. Аннотация @Retention
позволяет указать жизненный цикл аннотации: будет она присутствовать только в
исходном коде, в скомпилированном файле, или она будет также видна и в процессе
выполнения. Выбор нужного типа зависит от того, как вы хотите использовать
аннотацию, например, генерировать что-то побочное из исходных кодов, или в
процессе выполнения стучаться к классу через reflection.

http://www.seostella.com/ru/article/2012/05/21/annotacii-v-java-retention.html

@Documented — отмечает аннотацию для включения в документацию. Аннотация


@Documented указывает, что помеченная таким образом аннотация должна быть
добавлена в javadoc поля/метода и так далее. Например, класс, помеченный
аннотацией без @Documented, будет выглядеть так:

public class TestClass extends java.lang.Object

@Target — отмечает аннотацию как ограничивающую, какие элементы аннотации


могут быть к ней применены. Аннотация @Target указывает, что именно мы можем
пометить этой аннотацией, это может быть поле, метод, тип и т.д.

http://www.seostella.com/ru/article/2012/05/20/annotacii-v-java-target.html

@Inherited — отмечает, что аннотация может быть расширена подклассами


аннотируемого класса. Аннотация @Inherited помечает аннотацию, которая будет
унаследована потомком класса, отмеченного такой аннотацией.

261. Что такое web-сервер?

Веб-сервер — сервер, принимающий HTTP-запросы от клиентов, обычно веб-


браузеров, и выдающий им HTTP-ответы, как правило, вместе с HTML-страницей,
изображением, файлом, медиа-потоком или другими данными.

Веб-сервером называют как программное обеспечение, выполняющее функции веб-


сервера, так и непосредственно компьютер, на котором это программное обеспечение
работает.

262. Что такое Tomcat?

Tomcat (Catalina) — контейнер сервлетов с открытым исходным кодом,


разрабатываемый Apache Software Foundation. Реализует спецификацию сервлетов,
спецификацию JavaServer Pages (JSP) и JavaServer Faces (JSF). Написан на языке
Java.

Tomcat позволяет запускать веб-приложения и содержит ряд программ для


самоконфигурирования. Tomcat используется в качестве самостоятельного веб-
сервера, в качестве сервера контента в сочетании с веб-сервером Apache HTTP
Server, а также в качестве контейнера сервлетов в серверах приложений JBoss и
GlassFish.

263. Что такое сервлеты и где они используются?

Сервлет является интерфейсом Java, реализация которого расширяет


функциональные возможности сервера. Сервлет взаимодействует с клиентами
посредством принципа запрос-ответ, то есть обрабатывает запросы и возвращает
результат обработки.

Хотя сервлеты могут обслуживать любые запросы, они обычно используются для
расширения веб-серверов.

Жизненный цикл сервлета состоит из следующих шагов:

1) В случае отсутствия сервлета в контейнере.

- Класс сервлета загружается контейнером.

- Контейнер создает экземпляр класса сервлета.

- Контейнер вызывает метод init(). Этот метод инициализирует сервлет и вызывается в


первую очередь, до того, как сервлет сможет обслуживать запросы. За весь
жизненный цикл метод init() вызывается только один раз.

2) Обслуживание клиентского запроса. Каждый запрос обрабатывается в своем


отдельном потоке. Контейнер вызывает метод service() для каждого запроса. Этот
метод определяет тип пришедшего запроса и распределяет его в соответствующий
этому типу метод для обработки запроса. Разработчик сервлета должен предоставить
реализацию для этих методов. Если поступил запрос, метод для которого не
реализован, вызывается метод родительского класса и обычно завершается
возвращением ошибки инициатору запроса.

3) В случае если контейнеру необходимо удалить сервлет, он вызывает метод


destroy(), который снимает сервлет из эксплуатации. Подобно методу init(), этот метод
тоже вызывается единожды за весь цикл сервлета.

264. Какие режимы запуска приложений в IDEA вы знаете?

Обычный запуск приложения и запуск в режиме отладки.

Обычный запуск приложения - это обычно его выполнение.


В режиме отладки (Debug) же приложение можно выполнять построчно. Также в этом
режиме можно ставить точки останова (breakpoints), на которых программа будет
приостанавливать выполнение. Кроме того, этот режим позволяет смотреть значения
переменных во время выполнения программы.

265. Можно ли дебажить приложение/сервлет, которое запущено внутри Tomcat’а?

- Чтобы запустить отладку сервлета из IDEA, нужно сделать следующее:

- Зайти в найстроки отладки/запуска приложения

- Добавить конфигурацию Remote

- Далее выводится страница, где нужно изменить адрес хоста, на котором находится
Tomcat, и порт

- Открыть файл catalina.bat (для Windows) и исправить в нём строчку "set


DEBUG_OPTS=". Туда нужно дописать следующее

"- Xdebug Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1985".

- Последнее число - это адрес порта, который мы указали на шаге 3.

- Перестартовать Tomcat

- Выставить точки останова в коде в нужных местах

- Нажать Debug в IDEA

- Отправить запрос

- Произвести отладку из среды разработки

266. Как в IDEA установить точку остановки?

Щелкнуть ЛКМ в поле между номером строчки и началом строки, либо встать на
какую-то строчку и нажать ctrl+F8, либо встать на строку и в меню выбрать Run ->
Toggle line BreakPoint

267. Как в IDEA посмотреть список всех точек остановки?

Либо сочетанием клавиш ctrl+shift+F8, либо выбрать в меню Run -> View Breakpoints
268. Можно ли с помощью IDEA поменять значение переменной в процессе работы
программы?

Это можно сделать в режиме отладки. Во время отладки нужно в окне переменных
выбрать нужную переменную и нажать F2, либо щёлкнуть по переменной правой
кнопкой мыши и в открывшемся меню выбрать "set value", и ввести нужное значение
переменной.

269. Как в IDEA настроить отступы?

В настройках (Settings) выбрать Editor, потом — Code Style. Там уже можно изменить
настройки отступов для каждого поддерживаемого формата файла.

270. Как в IDEA настроить, чтобы { отображалось на той же строке, а не на новой?

Перейти по следующему пути Settings -> Editor -> Code Style -> Java -> Wrapping and
Braces, и дальше в разделе Braces Placement изменять настройки (для класса, метода,
лямбда-выражений и других случаев).

271. Что такое IP-адрес?

IP-адрес (от англ. Internet Protocol) - это уникальный числовой идентификатор


устройства в компьютерной сети, работающий по протоколу TCP/IP.

В версии протокола IPv4 IP-адрес имеет длину 4 байта, представляет собой 32-битное
число и записывается в виде четырёх десятичных чисел значением от 0 до 255
(эквивалентых четырём восьмибитным числам), разделённых точками, например,
192.168.0.3.

В версии протокола IPv6 IP-адрес имеет длину 16 байт, представляет собой 128-
битное число и записывается в виде восьми четырёхзначных шестнадцатеричных
чисел (эквивалентных восьми 16-битным числам), разделённых двоеточиями,
например, 2001:0db8:85a3:0000:0000:8a2e:0370:7334

272. В чем отличие host и domain?

Домен — это адрес сайта или определённая зона, имеющая уникальное имя в
системе доменных имён.

Хост — это определённый компьютер или сервер, подключенный к локальной или


глобальной сети. Хост обладает уникальным адресом в среде сервисов TCP/IP (IP-
адресом).

273. Какие методы в HTTP вы знаете?

GET - используется для запроса содержимого указанного ресурса. С помощью метода


GET можно также начать какой-либо процесс;
POST - применяется для передачи пользовательских данных заданному ресурсу. При
этом передаваемые данные включаются в тело запроса;

PUT - применяется для загрузки содержимого запроса на указанный в запросе URI.


Если по заданному URI не существует ресурс, то сервер создаёт его;

DELETE - удаляет указанный ресурс;

OPTIONS - используется для определения возможностей веб-сервера или параметров


соединения для конкретного ресурса;

HEAD - применяется для извлечения метаданных, проверки наличия ресурса


(валидация URL) и чтобы узнать, не изменился ли он с момента последнего
обращения. Аналогичен методу GET, за исключением того, что в ответе сервера
отсутствует тело. Запрос HEAD обычно;

PATCH - аналогично PUT, но применяется только к фрагменту ресурса;

TRACE - возвращает полученный запрос так, что клиент может увидеть, какую
информацию промежуточные серверы добавляют или изменяют в запросе;

LINK - устанавливает взаимосвязи между существующим ресурсом, указанным в URI-


запроса, и другими существующими ресурсами, не позволяет передавать в запросе
Тело-Запроса, в результате работы данного метода не создаются новые ресурсы;

UNLINK - удаляет одну или более ссылочных взаимосвязей для ресурса, указанного в
URI-Запроса;

CONNECT - преобразует соединение запроса в прозрачный TCP/IP-туннель, обычно


чтобы содействовать установлению защищённого SSL-соединения через
нешифрованный прокси;

274. Чем отличаются методы GET, POST и HEAD?

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

275. Что такое REST?

REST означает Representational State Transfer («передача состояния представления»)


- это популярный архитектурный подход для создания API в современном мире.

Существует шесть обязательных ограничений для построения распределённых REST-


приложений:
- Модель "Клиент-Сервер" (означает, что сеть должна состоять из клиента и сервера;
сервер - это тот, кто обладает ресурсами, клиент - тот, который их запрашивает))

- Отсутствие состояния (означает, что ни клиент, ни сервер не отслеживают состояния


друг друга)

- Кеширование (клиенты и промежуточные узлы могут кешировать результаты


запросов, а ответы сервера должны иметь явное или неявное обозначение, что они
кешируемые или некешируемые)

- Единообразие интерфейса (означает, что между клиентами и серверами существует


общий язык взаимодействия, который позволяет им быть заменяемыми или
изменяемыми, без нарушения целостности системы):

276. Зачем нужен класс Calendar в Java?

Для более удобной работы с датой и временем. Он позволяет работать с датой в


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

277. Как преобразовать дату в Java к нужному формату?

Для этого существует класс SimpleDateFormat. Объекту этого класс в аргументе нужно
передать шаблон представления даты в формате строки String. Затем
воспользоваться методом format(Date date) для преобразования даты в строку в
нужном формате либо parse(String date) для считывания объекта Date из строки в
нужном формате.

SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");

Date date = new Date();

String dateToString = formatter.format(date);

Date date = formatter.parse(dateToString);

http://www.seostella.com/ru/article/2012/02/05/formatirovanie-daty-v-java.html

Либо можно воспользоваться новым Java 8 Date Time API.

LocalDate now = LocalDate.now();

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");

String formattedDate = now.format(formatter);


LocalDate parsedDate = LocalDate.parse(formattedDate, formatter);

https://www.codeflow.site/ru/article/migrating-to-java-8-date-time-api

278. В чем отличие URI и URL?

URI (Uniform Resource Identifier, "унифицированный идентификатор ресурса") - это


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

URL (Uniform Resource Locator) - это некий унифицированный указатель на ресурс,


однозначно определяющий его месторасположение. URL служит
стандартизированным способом записи адреса ресурса в сети Интернет.

Их отличия в том, что URI — это некоторый идентификатор ресурса, который


позволяет этот ресурс как-то идентифицировать, а URL — это указатель на ресурс, он
даёт информацию о том, где находится ресурс. Таким образом URL — это URI,
который помимо идентификации ресурса, даёт информацию о его местонахождении.

279. Что такое сокеты?

Сокеты — это связка IP-адреса и порта, позволяющая из внешней сети


идентифицировать программу на компьютере или сервере. В Java для работы с
сокетами есть два класса Socket и ServerSocket. Класс Socket играет роль клиента,
класс ServerSocket - роль сервера. Клиент может отправлять и принимать сообщения
через сокет. Сервер же постоянно отслеживает запросы пользователей и отвечает на
них.

Для создания клиентского сокета (Socket) нужно указывать IP-адрес (или домен) и
порт.

Для создания серверного сокета (ServerSocket) – только порт. Серверный сокет


появляется только на том компьютере, где его создали. У класса ServerSocket есть
метод accept(), который, если его вызвать, будет ждать входящее соединение. Т.е.
метод будет выполняться бесконечно долго, пока какой-то клиентский сокет не
попробует обратиться к нему. Тогда метод accept() примет соединение, создаст объект
сокет для коммуникации и после этого вернет этот объект.

280. Отличие классов Socket и URL?

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

Класс Socket используется для связи с сервером (другой программой), а URL — для
доступа к ресурсу (например, к файлу). Кроме того, URL и URLConnection
ориентированы в основном на работу с HTTP, тогда как Socket может работать с
любыми протоколами.

Вам также может понравиться