the epic groovy puzzlers s02: the revenge of the parentheses

137
ЭПИЧНЫЕ ГРУВИ ПАЗЗЛЕРЫ ВТОРОЙ СЕЗОН: МЕСТЬ СКОБОК!

Upload: javadayua

Post on 06-Jan-2017

167 views

Category:

Software


3 download

TRANSCRIPT

ЭПИЧНЫЕ ГРУВИ

ПАЗЗЛЕРЫ

ВТОРОЙ СЕЗОН:

МЕСТЬ СКОБОК!

Ну этих точно никто не знает…

1. Дваклевыхпацанана сцене

Ты кто такой?

linkd.in/jbaruch

stackoverflow.com/users/402053/jbaruch

Как два?! А Где второй?!

Вместе мы:

Первый Сезон Хорошо Пошёл!

1. Дваклевыхпацанана сцене2. Смешные задачки3. Выголосуете! Да-да!4. Новыеклевыефутболкилетятв

зал! Лягушки тоже.5. Унас есть хэштег!

groovypuzzlers

Все работает (т.е. не работает) на версии 2.4.4

'а'..'я'.each { println it }

B. NoSuchMethodError

C. z

D. Не побежит

A. абв...я

Вы знали, да?

('a'..'z').each { println it }

“Все проблемы в программировании можно решить добавив пару скобок”

John McCarthy, изобретатель LISP

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.Три Баха

В рантайме отрабатывают только closures, всё остальное инлайнится

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

def beast = '6' * Math.PI

def beast = '6' * 3.1415926…

/**

* 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();

}

def beast = '6' * 3.1415926…

def beast = '6' * 3

Pop Quiz!

B. def beast = '6' * '3’

C. def beast = '667' – 1

D. def beast = '6' + '6' + 0 + 6

Куку!

@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]

TreaayeMap a = [5]

TreaayeMap a = [5]

TreaayeMap a = [5]@groovy.transform.InheritConstructors

class TreaayeMap extends HashMap {

}

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<THERE_CAN_BE_ONLY_ONE> clazz = THERE_CAN_BE_ONLY_ONE.class

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<THERE_CAN_BE_ONLY_ONE> clazz = (THERE_CAN_BE_ONLY_ONE as Class)

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()

}

}

Как мы это чиним?

String truth = 'false'

boolean groovyTruth = truth

println groovyTruth

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.fur

class Kitty { def fur }

def kitties

println kitties.fur

class Kitty { def fur }

def kitties

println kitties.collect { it.fur }

class Kitty { def fur }

def kitties

println kitties.collect { it.fur }

public static Collection asCollection(Object value) {

if (value == null) {

return Collections.EMPTY_LIST;

}

}

class Kitty { def fur }

def kitties

println kitties*.fur

class Kitty { def fur }

def kitties

println kitties*.fur

class Kitty { def fur }

def kitties

println kitties*.fur

[]nullCaught: java.lang.NullPointerException: Cannot get property 'fur' on null object

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 будет вызван!

Убираем елемент

assert 1L == 1println 1L.equals(1)

assert 1L == 1println 1L.equals(1)

A. Assertion failed

B. true

C. false

D. MissingMethodException

A. [[2, 3, 5], [2, 4, 8], [42, 73, 2147483647, 0]]

B. Не побежит

C. [[null, null, null, 5]]

D. null

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]:[]

def jailhouseRockdef loveMeTender

def rockAroundTheClock = [1,2,3]

false?null:true?[null]:[1,2,3]

def jailhouseRockdef loveMeTender

def rockAroundTheClock = [1,2,3]

false?null:[null]

def jailhouseRockdef loveMeTender

def rockAroundTheClock = [1,2,3]

[null]

Как мы это чиним?

(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