Вчера нас с телезрителями обвинили в том, что большинство вчерашних задач были связаны с Java весьма косвенно. Мы принимаем это обвинение, и поэтому сегодня у нас вариант на чистой Java! никаких спрингов, эксэмэлей и паттернов. Это будет настоящее испытание для истинных любителей хардкора!
Под катом — ответы на вчерашний раунд и суперблиц! Против знатоков сегодня играет телезритель из Петербурга Андрей apangin Паньгин.
Но сначала ответы на вчерашние задачи .
Скомпилируется ли следующий аспект AJC компилятором?
Если да — то что он выведет на консоль при компиляции?public aspect QuizAspect {
public static int count(int i) {
return i++;
}
before (int n) : execution(public int QuizAspect.count(int))
&& args(n) && if(QuizAspect.count(1)>1) {
System.out.println("QuizAspect " + n);
}
}
Правильный ответ. Скомпилируется успешно, но ничего не выведет на консоль при компиляции. При этом вызов метода Quiz.count в рантайме приведет к StackOverflowError ошибке!
Можно подумать, что выражение в if() начнет выпоняться при компиляции кода, но это не так.
(не стоит путать аспекты с мета программированием)
Аспект лишь встроит код совета внутрь метода count, добавит if() к этому коду.
В чём подвох удалять Java-комментарии таким выражением? Укажите 3 причины, почему так делать нельзя. (считаем, что исходник написан нормальными символами) —
Pattern.compile("/\\*(?:[^*]|\\*[^/])*\\*/")
Ответ
- Если это джавовская строка, а в ней якобы комент — то не будет работать
- Если комент заканчивается на две звездочки слэш, то работать не будет
- Если комментарий большой, то получим Будет StackOverflowError, т.к. java regexp’ы используют backtracking.
Пофиксить можно двумя способами:
- Possessive quantifier:
Pattern.compile("/\\*(?:[^*]|\\*[^/])*+\\*/")
- Independent group:
Pattern.compile("/\\*(?>,[^*]|\\*[^/])*\\*/")
Есть 2 Spring контекста:
1. a.xml с бином
<util:list id="myList">
<value>3</value>
<value>4</value>
</util:list>2. b.xml с бином
<util:list id="myList">
<value>6</value>
</util:list>Что напечатает такой фрагмент кода:
System.out.println(new ClassPathXmlApplicationContext("a.xml", "b.xml").getBean("myList"));
И как можно заставить его бросить ошибку, не изменяя логику работы кода?
Ответ
Выведет 6, а заставить бросить ошибку можно установив allowBeanDefinitionOverriding у контекста в false.
А теперь самая хардкорная задача вчерашнего дня, по мнению президента, премьера и министра обороны элитарного клуба.
Ниже приведены 2 программы. Каждая из них пытается аллоцировать суммарно памяти больше размера хипа. Но одна из них выкидывает java.lang.OutOfMemoryError, а вторая нет. Почему?
public class OOM1 {
private static final int SIZE = (int) (Runtime.getRuntime().maxMemory() * 0.55);
public static void main(String[] args) {
{
byte[] bytes = new byte[SIZE];
System.out.println(bytes.length);
}
byte[] bytes1 = new byte[SIZE];
System.out.println(bytes1.length);
System.out.println("I allocated memory successfully");
}
}
public class OOM2 {
private static final int SIZE = (int) (Runtime.getRuntime().maxMemory() * 0.35);
public static void main(String[] args) {
{
byte[] bytes = new byte[SIZE];
System.out.println(bytes.length);
}
byte[] bytes1 = new byte[SIZE];
System.out.println(bytes1.length);
byte[] bytes2 = new byte[SIZE];
System.out.println(bytes2.length);
System.out.println("I allocated memory successfully");
}
}Ответ
В обоих случаях javac понимает, что переменная bytes не будет использована после окончание внутреннего блока. Поэтому второй созданный массив, который мы кладем в переменную bytes1, займет тот же слот, что и переменная bytes. Как следствие, после выполнения присваивания bytes1 < — new bytes[SIZE] значение, которое было в переменной bytes становится недоступным и GC может его удалить. Тем самым OOM2 требует всего лишь 70% от хипа, а не 105%.
Желающие узнать ответы — попробуйте написать им в личку. Может быть они сжалятся над вами!
Суперблиц от Андрея Паньгина
Вот и настало время истинного хардкора! Знатоки поднимают глаза вверх, и на их экранах появляется улыбающийся apangin. Он кагбэ машит всем знатоками и кидает им тысячи воздушных поцелуев.
Вопрос первый
Что не так с этим кодом? Как его исправить?
public static double[] getRandomVector(int size) {
double[] vector = new double[size];
Arrays.parallelSetAll(vector, i -> Math.random());
return vector;
}
Вопрос второй
Как такое может быть, что публичный метод работает заметно быстрее идентичного приватного?
public class Modifiers {
static final Inner inner = new Inner();
static class Inner {
int x = 1;
int getX1() { return x; }
int getX2() { return getX1(); }
int getX3() { return getX2(); }
int getX4() { return getX3(); }
int getX5() { return getX4(); }
int getX6() { return getX5(); }
int getX7() { return getX6(); }
int getX8() { return getX7(); }
int getX9() { return getX8(); }
private int getPrivate() { return getX9(); }
public int getPublic() { return getX9(); }
}
@Benchmark
public int testGetPrivate() {
return inner.getPrivate();
}
@Benchmark
public int testGetPublic() {
return inner.getPublic();
}
}
Вопрос третий
Можно ли в Java создать класс (именно класс, не интерфейс) без единого конструктора, даже приватного?
Такие дела!
Ваши ответы пишите ниже в комментариях под спойлером. У вас есть 12 часов. Решившие все три задачи получат специальный приз от Андрея и JUG.ru.
Ответы — традиционно на хабре, но уже после JPoint.
Удачи!
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий