the epic groovy puzzlers s02: the revenge of the parentheses
TRANSCRIPT
1. Дваклевыхпацанана сцене2. Смешные задачки3. Выголосуете! Да-да!4. Новыеклевыефутболкилетятв
зал! Лягушки тоже.5. Унас есть хэштег!
groovypuzzlers
def back = 'back'
def quotes = ["I'll be $back",
"I'll be ${-> back}",
"I'll be ${back}",
"I'll be "+back]
println quotes
back = 'bach'
println quotes
A.Никаких Бахов
B.Один Бах
C.Два Баха
D.Три Баха
def back = 'back'
def quotes = ["I'll be $back",
"I'll be ${-> back}",
"I'll be ${back}",
"I'll be "+back]
В рантайме отрабатывают только closures, всё остальное инлайнится
def back = 'back'
def quotes = ["I'll be $back",
"I'll be ${-> back}",
"I'll be ${back}",
"I'll be "+back]
В рантайме отрабатывают только closures, всё остальное инлайнится
А это единственный closure
Как напечатать 666?
A. def beast = '6' * Math.PI
B. def beast = '6' * '3’
C. def beast = '667' – 1
D. def beast = '6' + '6' + 0 + 6
/**
* Repeat a String a certain number of times.
*
* @param self a String to be repeated
* @param factor the number of times the String should be repeated
* @return a String composed of a repetition
* @throws IllegalArgumentException if the number of repetitions is < 0
* @since 1.0
*/
public static String multiply(String self, Number factor) {
int size = factor.intValue();
…
}
@groovy.transform.InheritConstructors
class TreaayeMap extends HashMap {
}
TreaayeMap a = [5]
TreaayeMap b = [6]
println "${a.getClass()} ${a.equals(b)}"
@groovy.transform.InheritConstructors
class TreaayeMap extends HashMap {
}
TreaayeMap a = [5]
TreaayeMap b = [6]
println "${a.getClass()} ${a.equals(b)}"
A. class HashMap true
B. class TreaayeMap false
C. class TreaayeMap true
D. class HashMap false
TreaayeMap a = [5]@groovy.transform.InheritConstructors
class TreaayeMap extends HashMap {
}
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
* capacity and the default load factor (0.75).
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
public HashMap(int initialCapacity)
class THERE_CAN_BE_ONLY_ONE { }
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class clazz = THERE_CAN_BE_ONLY_ONE
return clazz.newInstance()
}
}
println new MacLeod().THERE_CAN_BE_ONLY_ONE
class THERE_CAN_BE_ONLY_ONE { }
class MacLeod {
THERE_CAN_BE_ONLY_ONE
getTHERE_CAN_BE_ONLY_ONE() {
Class clazz = THERE_CAN_BE_ONLY_ONE
return clazz.newInstance()
}
}
println new MacLeod().THERE_CAN_BE_ONLY_ONE
A. Не побежит
B. No such property: THERE_CAN_BE_ONLY_ONE for class: MacLeod
C. THERE_CAN_BE_ONLY_ONE@3d74bf60
D. Навернется по-другому
A.MultipleCompilationErrorsException
B.StackOverflowError
C.NullPointerException
D.Навернется ещё как-нибудь
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class clazz = THERE_CAN_BE_ONLY_ONE
return clazz.newInstance()
}
}
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class clazz = getTHERE_CAN_BE_ONLY_ONE()
return clazz.newInstance()
}
}
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class<THERE_CAN_BE_ONLY_ONE> clazz = THERE_CAN_BE_ONLY_ONE.class
return clazz.newInstance()
}
}
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class<THERE_CAN_BE_ONLY_ONE> clazz = getTHERE_CAN_BE_ONLY_ONE().class
return clazz.newInstance()
}
}
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class<THERE_CAN_BE_ONLY_ONE> clazz = (THERE_CAN_BE_ONLY_ONE as Class)
return clazz.newInstance()
}
}
class MacLeod {
THERE_CAN_BE_ONLY_ONE getTHERE_CAN_BE_ONLY_ONE() {
Class<THERE_CAN_BE_ONLY_ONE> clazz = (getTHERE_CAN_BE_ONLY_ONE() as Class)
return clazz.newInstance()
}
}
A.false
B. true
C. ClassCastException
D.Не побежит
String truth = 'false'
boolean groovyTruth = truth
println groovyTruth
class Kitty { def fur }
def kitties = [new Kitty(fur: 'soft'),new Kitty(fur: 'warm'),new Kitty(fur: 'purr') ]
println kitties.collect { it.fur }
println kitties*.fur
println kitties.fur
Сколько будет одинаковых строк?
A. Все разные
B. Две одинаковые
C. Все одинаковые
D. Не скомпилируется
class Kitty { def fur }
def kitties
println kitties.collect { it.fur }
println kitties*.fur
println kitties.fur
Сколько будет одинаковых строк?
A. Все разные
B. Две одинаковые
C. Все одинаковые
D. Не скомпилируется
class Kitty { def fur }
def kitties
println kitties.collect { it.fur }
public static Collection asCollection(Object value) {
if (value == null) {
return Collections.EMPTY_LIST;
}
…
}
ArrayList<String> expendables = [Arnie', 'Chuck', Sly']
def expendable = //кто нибудь из списка сверху
for(String hero in expendables) {
if(hero == expendable){
expendables.remove(hero)
}
}
println expendables
A. Никого
B. Arnie
C. Chuck
D. Sly
ArrayList<String> expendables = [Arnie', 'Chuck', Sly']
def expendable = //кто нибудь из списка сверху
for(String hero in expendables) {
if(hero == expendable){
expendables.remove(hero)
}
}
println expendables
Кого подставить чтобы не было ConcurrentModificationException?
List expendables = Arrays.asList(new String[]{”Arnie", "Chuck", ”Sly"});
String expendable = "Chuck";
Iterator iterator = expendables.iterator();
while(iterator.hasNext()) {
String hero = (String)iterator.next();
if(hero.equals(expendable)) {
expendables.remove(hero);
}
}
Декомпильнём-ка!
while(iterator.hasNext()) {
String hero = (String)iterator.next();
if(hero.equals(expendable)) {
// expendables.remove(hero); }
}
while(iterator.hasNext()) {
String hero = (String)iterator.next();
if(hero.equals(expendable)) {
// expendables.remove(hero); }
}
public E next() {
checkForComodification();
…
cursor = i + 1;
}
Модификации
проверяются в
следущем заходе
Готовим индекс к
проверке hasNext() в
следующем заходеpublic boolean hasNext() {
return cursor != size();
}
Выход по индексу
последнего элемента +1 ==
size()
Посмотрим как должно
работать
while(iterator.hasNext()) {
String hero = (String)iterator.next();
if(hero.equals(expendable)) {
// expendables.remove(hero); }
}
public E next() {
checkForComodification();
…
cursor = i + 1;
}
public boolean hasNext() {
return cursor != size();
}
После Слая курсор равен
3
Size тоже равен 3
Всё ясно. Теперь давайте попортим.
while(iterator.hasNext()) {
String hero = (String)iterator.next();
if(hero.equals(expendable)) {
expendables.remove(hero);
}
}
public E next() {
checkForComodification();
…
cursor = i + 1;
}
public boolean hasNext() {
return cursor != size();
}
В итерации Чака курсор
равен 2
Оп-ля, и size теперь тоже
равен 2!
А всё, никаких next() не будет,
checkForComodification не вызывается!
Теперь мы убираем Чака
while(iterator.hasNext()) {
String hero = (String)iterator.next();
if(hero.equals(expendable)) {
expendables.remove(hero);
}
}
public E next() {
checkForComodification();
…
cursor = i + 1;
}
public boolean hasNext() {
return cursor != size();
}
В итерации Слая курсор
равен 3
Теперь размер 2!
2!=3, пошли на еще кружок!
Не важно, что мы уже за концом цикла,
checkForComodification будет вызван!
Убираем елемент
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
jailhouseRock?:[] + loveMeTender?:[] + rockAroundTheClock?:[]
*Да, это не Элвиса, мы знаем.
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
jailhouseRock?:[] + loveMeTender?:[] + rockAroundTheClock?:[]
A. [null]
B. null
C. []
D. [1,2,3]
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
jailhouseRock?:[] + loveMeTender?:[] + rockAroundTheClock?:[]
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
jailhouseRock?:[null]?:[] + rockAroundTheClock?:[]
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
jailhouseRock?:[null]?:[1,2,3]?:[]
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
jailhouseRock?jailhouseRock:[null]?[null]:[1,2,3]?[1,2,3]:[]
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
null?null:[null]?[null]:[1,2,3]?[1,2,3]:[]
def jailhouseRockdef loveMeTender
def rockAroundTheClock = [1,2,3]
false?null:true?[null]:true?[1,2,3]:[]
Как мы это чиним?
(jailhouseRock?:[])+(loveMeTender?:[])+(rockAroundTheClock?:[])
Ну, вы в курсе, да?
class Test {
void run() {
long start = System.nanoTime()
try {
throw new Exception('fail!')
}
finally {
long end = System.nanoTime()
long time = end - start
println time
}
}
}
new Test().run()
A. 254106635 Caught: java.lang.Exception: fail!
B. Caught: java.lang.Exception: fail!254106635
C. MissingPropertyException: No such property: time for class: Test
D. Не побежит
Как работает finally?
def a
try {
//хрень или случится, или нет
a = 'a'
} catch (Exception e) {
a = 'a'
throw e
}
try {
//хрень или случится, или нет
} finally {
def a = 'a'
}
А вот что нам сгенерилосьlong start = System.nanoTime()
long end //это сгенерилось
//а где мой long time?!
try {
throw new Exception('fail!')
end = System.nanoTime()
time = end - start
println time
} catch (Exception e){
end = System.nanoTime()
time = end - start
println time
throw e
}
Как мы это чиним?
class Test {
void run() {
long start = System.nanoTime()
try {
throw new Exception("fail!")
}
finally {
long end = System.nanoTime()
long time
time = end - start
println time
}
}
}
new Test().run()
Как мы еще это чиним?
long start = System.nanoTime()
try {
throw new Exception('fail!')
}
finally {
long end = System.nanoTime()
long time = end – start
println time
}
А еще можно вот так
@CompileStatic
class Test {
void run() {
long start = System.nanoTime()
try {
throw new Exception('fail!')
}
finally {
long end = System.nanoTime()
long time = end - start
println time
}
}
}
new Test().run()
Кстати, время изменилось с 254106635 на 56845
1. Пишитечитабельныйкод
2. Комментируйте всетрюки
3. Иногда этобаг
4. Пользуйте static code analysis - intellij IDEA!
5. Rtfm
6. Скобки! Всегда добавляйте скобки!
Мыпродолжаемразвлекаться! (смотритекакиеужефутболочкиняшные!)
Наткнулисьнапаззлер? Давайтеегосюда!- puzzlers jfrog.com- Groovypuzzlers
Понравилось?Хвалитенасвтвиттерескорее!
groovypuzzlers- Groovypuzzlers- jekaborisov- jbaruch
Непонравилось?/dev/null