13. 11. 2017

Jak smazat na Oraclu unique constraint i s indexem

Vážení diváci, vítejte u dnešní databázové krimi-telenovely!

Epizoda 1

Mějme Oracle databázi 11.2.0.2.0 a v ní tabulku, která má kromě primárního klíče i unique constraint na jinou skupinu sloupců (v praktickém případě, z nějž vychází tento blogpost, byly dva, ale pro demonstraci na minimalistickém příkladě stačí jeden). Pokud založíme constraint příkazem alter table ... add constraint ..., založí se automaticky i index, jak se lze přesvědčit následujícím dotazem:

create table foo (id varchar(26) not null, name varchar(50) not null);
alter table foo add constraint pk_foo primary key (id);
alter table foo add constraint un_foo unique (name); 
select * from all_indexes where table_name = 'FOO' and index_name = 'UN_FOO';
insert into foo values ('id1','name');

Table FOO created.
Table FOO altered.
Table FOO altered.
<1 řádek>
1 row inserted.

V tomto bodě se stane zločin, který se divák dozví až v Epizodě 3.

Epizoda 2


Uplyne nějaký čas a při dalších požadavcích na změnu systému zjistíme, že unique constraint už není unique a databáze se musí zrefaktorovat. Není problém, constraint jednoduše dropneme a jak se lze přesvědčit, zmizel i index a již lze zadávat duplicity:

alter table foo drop constraint un_foo;
select * from all_indexes where table_name = 'FOO' and index_name = 'UN_FOO';
insert into foo values ('id2','name');

Table FOO altered.
<0 řádků>
1 row inserted.

Epizoda 3


Ukáže se že skript z Epizody 2 na některých prostředích nefunguje spolehlivě – po alteru sice constraint zmizí, ale index zůstane viset. Takže jako kdyby tam constraint zůstal. Protože při deploymentu se vyjede jen alter, vše se tváří ok a uživatelé vše poznají, až když dostávají chyby v aplikaci, které neprochází insert.

Pátráním přicházím na to, že ve stavu, do kterého se databáze dostala z nuly po vyvolání skriptu v Epizodě 1, funguje skript správně. Pokud ale po Epizodě 1 databázi zazálohuji v SQL Developeru (menu Tools -> Database copy) a vzápětí obnovím, skript selže a index se nesmaže. Zločinem je tedy zálohování databáze a vrahem není zahradník, ale SQL Developer. Co se konkrétně stalo?

Jak je uvedeno výše, vytvoření constraintu vede automaticky k vytvoření indexu. Toto vytvoření se do zálohovacího skriptu promítne jako explicitní příkaz. Takže obnovu ze zálohy už dělá jiný skript:

create table foo (id varchar(26) not null, name varchar(50) not null);
alter table foo add constraint pk_foo primary key (id);
CREATE UNIQUE INDEX un_foo ON foo (name);
alter table foo add constraint un_foo unique (name);
select * from all_indexes where table_name = 'FOO' and index_name = 'UN_FOO';
insert into foo values ('id1','name');

Posledními dvěma příkazy select a insert lze ověřit, že obnova je k nerozeznání shodná s efektem původního skriptu. Bohužel je tu jeden rozdíl a ten je klíčový – při tvorbě indexu explicitním příkazem se takový index nesmaže pouhým dropnutím constraintu.

Epizoda 4

Tak ho dropnem zvlášť, co je na tom?

alter table foo drop constraint un_foo;
drop index un_foo;

Chyba! Příkaz drop index un_foo; zfailuje v prvním případě, kdy index vznikl implicitně a byl tedy příkazem alter table foo drop constraint un_foo; řádně smazán. Bohužel nic jako drop index un_foo if exists; neexistuje. Slepá větev.

Ok, googlím a najdu toto (pozn. hash v odkazech je podstatná – linkuji vždy konkrétní odpověď ve vlákně). Rada se sice týká dropnutí primary key, ale syntaxe připouští pro unique constraint klauzuli cascade taky. Nicméně dostaneme:

alter table foo drop constraint un_foo cascade;
select * from all_indexes where table_name = 'FOO' and index_name = 'UN_FOO';

Table FOO altered.
<1 řádek>

takže index nezmizel. Opět slepá větev.

Epizoda 5

Kolega radí použít syntax drop primary key ... drop index. To sice není přímo náš případ, neboť nedropujem primary key, ale vzhledem k ukecanosti SQL snaze SQL podobat se přirozenému jazyku se nabízí zkusit to i s constraintem.

alter table foo drop constraint un_foo drop index;
select * from all_indexes where table_name = 'FOO' and index_name = 'UN_FOO';

Table FOO altered.
<0 řádků>

Wow, funguje! Vyzkoušeno na případ jak s implicitně, tak s explicitně založeným indexem.
Šlape dobře, takže odesílám pull request.

Epizoda 6

Kolega, který dělá review pull requestu, se zajímá, kde jsem vzal tu syntax, že ji nikde neviděl. Pomyslím si – stačí ukázat příslušný railroad diagram v dokumentaci a je vymalováno. Nalistuji syntaxi neterminálu drop_constraint_clause v příkazu alter table:


Oops! V případě primárního klíče nebo nepojmenované unique n-tice sloupců je podporováno dropnutí (nebo naopak přání nechtít dropnout) i indexu. Pro drop pojmenovaného constraintu ale nic takového neexistuje. Proč to tedy funguje?

Začínám pátrat. Nacházím zmínku o této syntaxi přímo na AskTomu (sice pro KEEP INDEX, ale to neva, podle syntaktického diagramu je to taky blbě). Dost málo na to si myslet, že to stačí. Není sekvence symbolů alter table ... drop constraint ... drop index jen nějaká jiná – řečí teorie jazyků – derivace neterminálu, kterou v railroad diagramu nevidím? (Např. drop_constraint_clause v Oraclu 12 už je opakující se, takže kdyby připouštěla expanzi pouze na drop index, dvě opakování by náš výraz složily. Smůla. Podobně to nejde rozvinout ani v syntaxi Oracle 8.)

Epizoda 7

Když nezabralo UTFG (Use The Friendly Google), zabere Use The Friendly Stack Overflow. Posílám otázku. Kromě jednoho rychlého ochotného dobrovolníka, který otázce snaživě odebral tag database, ale jinak odpovídal na něco jiného, než jsem se ptal (a po upozornění svoji odpověď briskně smazal), jinak žádná odpověď.

Epizoda 8


Ok, zeptám se přímo na AskTomu. Poprvé kladu dotaz na AskTomu, takže mě čeká registrační proces Oracle účtu s mraky údajů a potvrzovacích checkboxů. Samozřejmě nejprve hledám, zda dotaz již nebyl položen. Dotaz sice nenacházím (myslím k syntaxi – samotný problém mazání je rozebrán víc než dost a záměrně ho do tohoto blogpostu netahám, jako intro lze použít např. toto), ale zato nacházím další výskyty zmíněné syntaxe – přímo od Toma Kyta plus v komentáři u odkazovaného blogu.

Posílám otázku (koukám, jak je rozlámaná, nicméně v preview před odesláním otázka takhle rozlámaná nebyla – Markdown asi do Oraclu ještě nedorazil). Ještě před posláním modeluju situaci na livesql.oracle.com, neboť slibují, že otázkám podpořeným ukázkou se dostane rychlejšího vyřízení. (Zrovna ta site jako na potvoru prochází maintenance pauzou, ale než dopíšu text otázky, je zase up.)

Odpověď od Chrise Saxona je rychlá, ochotná a k věci. Po doplňujícím review a další odpovědi z toho celkově plyne:
  • nejprve vtip: když to funguje, musí to být syntakticky správně
  • pak domněnka: vypadá to na dokumentační chybu, nicméně nepotvrzeno a může to být i nezamýšlený side efekt (čekal jsem trochu jasnější vyjádření)
  • syntaxe je zmíněna i v My Oracle Support (pro mě asi rozhodující argument – sice tam nemám přístup, ale vím, že MOS má pověst alternativní dokumentace a nepředpokládám, že by provedli tak radikální zásah a syntaxi náhle přestali podporovat)
  • absolutně bezpečné je údajně pouze to, co je v dokumentaci. Na náš případ by se tedy hodilo použít alter table foo drop unique (name) drop index;

Závěr

Poslední zmíněná syntaxe opravdu funguje i je v souladu s dokumentací. Nicméně vzhledem k ostatním okolnostem jsem zůstal u té původní. Byl to zajímavý výlet do světa Oraclu, na kterém mne překvapila existence nezdokumentované syntaxe i způsob, jakým se lze k takovým informacím dobrat. Problém byl zajímavý i tím, že AskTom byl vhodnějším místem pro jeho řešení než Stack Overflow.

22. 10. 2017

Wisephora 2017

Letošní 31. květen (čtete správně - po přepisu 75% poznámek začalo divoké léto a čas na dopsání jsem si našel až teď, nicméně doufám, že budou poznámky pro Vás mít cenu i tak) se v prostorách pražské La Fabriky uskutečnil 2. ročník konference Wisephora - setkání zájemců o téma budoucnost práce a zoologická zahrada nejrůznějších více či méně převratných myšlenek více či méně podložených praxí.

Protože už to nebylo poprvé, samozřejmě jsme většina TopMonků prožívala spolu s pořadatelským týmem všechna očekávání, vychytávání loňských much a vůbec porovnávání s loňskem. A následující referát píšu nejen jako revanš a poděkování za volňáska, ale i pro utřídění a perzistenci chaotických ručně psaných poznámek.

Výpisky z jednotlivých talků

Hned první talk Daniela France – O mravencích a lidech jsem vynechal z důvodu nárazové pomoci organizátorům. Ale to byl jediný vynechaný talk. Mimochodem jsem na něj pak slyšel jen chválu.

Vladi Briestenská – Pojďme sabotovat kancelářskou monokulturu

  • téma diverzity ve firmě
  • někdo řešil problém: proč je mnoho videí nahrávaných na YouTube vzhůru nohama? Protože mobilní aplikaci na natočení videa navrhovali praváci (ovládací tlačítko nahrávání dali na pravou stranu displeje) a nenapadlo je otestovat ji na levácích – leváci tím pádem drželi mobil obráceně. No předpokládám mlčky, že to je problém z doby, kdy mobily neměly gravitační čidlo, nicméně nenechme si takovým hnidopišstvím zkazit hlavní myšlenku: nespoléhat se, že všichni jsou jako já, snažit se vyjít z bubliny mně podobných jedinců
  • příběh Spotify, kde pevné vánoční volno nahradili pružným obecným volnem na svátek, protože zaměstnanci, jejichž kulturní zázemí Vánoce neuznává, se cítili diskriminováni (vyjasněno až po talku, na něm mi to vyznělo spíš jako zrušení Vánoc)
  • diversity trainings naopak posilují stereotypy – když firma nažene zaměstnance do často draze zaplaceného programu (aktivita, proces, teambuilding), jehož účelem je zbořit předsudky, úmysl je sice dobrý, ale výsledek bývá opačný
  • affinity bias = když nahiruju zaměstnankyni, která mi připomíná dobrou kamarádku z dětství
  • doporučení online aplikace: https://implicit.harvard.edu/
Odlišnost, ať už v jakékoli oblasti, je něco, k čemu se dnes společnost neumí postavit a upadá do extrému buď agrese v podobě odmítání a diskriminace nebo lhostejnosti v podobě relativizace a naředění rozdílů, umělé rovnosti a "vlády menšiny". Nepočítaje sekundární klišé, s jakými se zástupci extrémních táborů navzájem vnímají. Zlatou střední cestu vidím ve stavu, kdy většina projevuje vůči odlišné menšině toleranci a snahu vyjít z komfortní zóny, menšina však této tolerance nezneužívá, dokáže ustoupit a přitom předmět své odlišnosti zná a uchová. (Dosaďte si cokoli: leváky, programátory v X, věřící v cokoli, vegany, LGBT, ...) Z příkladu s leváky taky plyne, že odlišnost by neměla být samoúčelná, ale měla by přinášet užitek celku. (Jedna z topmonksích company values zní Weirdness, nonconformity is welcome a představuju si pod ní přesně to, že můžu být exot, ale ať to má hodnotu pro ostatní.)

Talk se mi v průběhu zdál, že zapadá spíš do druhého zmíněného extrému a proto jsem to ještě chtěl probrat osobně (zejména kvůli ukázce se Spotify, domnívám se, že uvedený postup je snad akceptovatelný u distribuované nadnárodní firmy, u malé české firmy by asi narazil). Oceňuji téma jako takové, dotýká se trochu etických otázek, což jsem u loňské Wisephory postrádal. Zazdil to ale závěr – úmysl poukázat na diverzitu mezi posluchači dobrý, ale exekuce v podobě řady intimních otázek do publika vyloženě necitlivá.  🌟🌟🌟

Roman Chlupatý – Revoluce práce je tu. (Ne)bojte se!

  • oceňuji zmínění prohlubování sociálních rozdílů, mizení střední třídy
  • zpochybnění účinnosti nepodmíněného příjmu (nebyl jediný přednášející s tímto názorem, chce se mi dodat: a je to tady, hlavně jaký to byl minulou Wisephoru hit) 🌟🌟

Pavol Lupták – Nejsvobodnější společnost

  • přednášející z IT security společnosti https://nethemba.com/
  • podporuje projekt http://www.nepracujemeprestat.sk/ – firmy, mezi jejichž etické hodnoty patří nepřijímání zakázek od státní správy
  • "Vysoce inteligentní lidé mají problém být zaměstnán v hierarchické struktuře."
  • 6 pilířů svobodné firmy: decentralizace (remote working), internal competition, voluntarism, consistency (odstrašující případ státu, který schvaluje nové zákony a množství výjimek), fairness (pevné mzdy nejsou fér), strong ethical rules
Oceňuji fungování firmy, kterou přednášející vybudoval. Mnohé z uvedených pilířů se dají namapovat na naše topmonksí hodnoty. Nicméně z hlediska celkového světonázoru přednášejícího jsem jinde. Písnička o tom, jaký je stát zlo, je utopistická a aktivity jako projekt nepracujemeprestat.sk mi přijdou jako póza (přestože to firma samotná vnímá jako projev konzistence). Pochopil bych nechuť pracovat na určitých konkrétních oblastech (např. EET), ale takto paušální odmítnutí vnímám jen jako opačný extrém k fenoménu státních, korupcí prolezlých legacy IT zakázek. I tvrzení o vztahu inteligentních lidí k hierarchické struktuře je černobílé – není to o inteligenci, ale o schopnosti vidět v té struktuře smysl. Celkový dojem z přednášky: postrádal jsem v ní lidskost. Jako ve všem, co je ovlivněno tzv. anarchokapitalismem. 🌟🌟

Zdeněk Cendra – Nápad, investoři, exekuce, prodej. Všechno je dnes dokonale popsané. Na konci na leadra firmy zůstane to nejtěžší: vše uřídit.

  • provozuje https://www.cdn77.jobs/, https://www.peering.cz/, https://10gbps.io/
  • lidi nespolupracují na základě rolí, ale podle toho, co umí
  • aktivně odmítá lidi s příliš dlouhou zkušeností ve velkých korporacích (někoho, kdo 8 let řídil pobočkovou síť v O2)
  • má pouze 2 procesy na firmu: 1. platíme včas a 2. poslední zamyká
  • písemný monthly CEO report – kontext do firmy, aktivní report vyjadřující stav firmy. (To se mi líbí, na našich projektech vedeme tzv. deníčky, ale samotné firemní informace sdělujeme ústně, byť pravidelně.)
  • soft skills > hard skills
  • pravidlo "kdo si člověka do firmy přijme, ten si ho taky vyhodí"
Pozitivní a velmi zábavný talk. Ve srovnání s předchozím jsem měl stejný dojem schopného člověka, který vybudoval dobře fungující firmu, ale zde jsem navíc měl dojem, že tam jsou normální lidi. 🌟🌟🌟🌟🌟

Matěj Krejčí – Spokojený zaměstnanec (lightning talk)

  • zdroje spokojenosti: 1. peníze (nejsou nejlepší motivátor), 2. spoluvlastnictví, 3. pocit z vykonané práce, 4. jistota dlouhodobého závazku, 5. sdílení, 6. ocenění osoby
Rozcvičovací začátek (postavit se a podat si ruku a usmát se na souseda vlevo a vpravo). Někdo to nemá rád, ale jako "ledoborec" to funguje a bylo to v tu chvíli milé. Přednášející pochází ze stejné společnosti jako loni Petr Ludwig (GrowJob), i slajdy v podobném schematickém stylu s ručně psaným fontem. Systematické povídání. 🌟🌟🌟

Michal Kalousek – Budeme všichni Profinauti? (lightning talk)

  • statistická fakta o nezaměstnanosti podložená výzkumem LMC
  • aplikace pro nalezení práce v blízkosti domova
  • aplikace pro nalezení lidí ("profinauti") ochotných pracovat pro moji firmu (doporučení ze známých)  
Celkem nepokrytě reklama na zmíněné dvě aplikace. Ale měl jsem aspoň dojem, že ty aplikace mohou být někomu užitečné.  🌟🌟

Senta Čermáková – Pro koho dnes chceme pracovat? Pro startupy, nebo pro inovační obry skupiny GAAF?

  • GAAF = Google + Amazon + Apple + Facebook, to jen tak na dovzdělání v newspeaku
Pro mě ne příliš zajímavý talk, jelikož většina byla tvořena poměrně abstraktním popisem programu Deloitte na podporu inovátorů proloženým futuristickými prognózami ve stylu přípravy na new-tech společnost s čipy a zbytek tvořilo autobiografické povídání přednášející o tom, jak jako úspěšná manažerka hledala další uplatnění. 🌟

Václav Lavička – Aby hodnocení lidí tvořilo hodnoty

Tady mám bias, Václav je tak trochu kolega, protože PurposeFly je startup vzešlý z TopMonks. V TopMonks zkoušíme Franka sami na sobě a zažil jsem nejen výstup z programu, ale i 1:1 setkání nad interpretací těchto výsledků s Václavem jakožto koučem. Každopádně jestliže se o všech lightning talkách dá říct, že to nakonec byla reklama na firmu nebo produkt příslušného přednášejícího, pak u tohoto talku mi to přišlo nejméně explicitní. 🌟🌟🌟🌟

Tomáš Vodenka – Proč "svoboda v práci" nemůže fungovat?

  • přirovnání zprofanovaného pojetí slova svoboda k zprofanovanému "miluji tě"
  • Socha Svobody na východním pobřeží USA by měla být vyvážena Sochou Zodpovědnosti na pobřeží západním. (něčí citát)
  • svoboda je výsledek, ne prostředek –> nelze zavést jako firemní kultura
  • 3 různé otázky: 1. co lidé chtějí, aby byli šťastni?, 2. co lidé chtějí, aby byli spokojeni?, 3. co lidé potřebují, aby byli spokojeni?
  • dělat lidi lepšími, ne šťastnějšími (Steve Jobs – chcete-li, aby byli šťastnější, prodávejte zmrzlinu)
  • nenutit ostatní rozhodovat, pokud nejsou připraveni, ale podporovat v přijetí odpovědnosti 🌟🌟🌟

Kristina Pomothy – Dnešek a zítřek pracovních prostorů

  • téma pracoviště a důležitosti on-site přítomnosti
  • Allen curve – s rostoucí vzdáleností klesá míra komunikace
  • rostoucí míra komunikace je předpokladem rostoucí míry inovace
  • design pracovního prostředí – zásady 3 P:
  • Proximity – je o tom, jak moc si jsou pracovníci blízko, jak sesadit týmy k sobě (příklad týmů, které potřebovaly těsně spolupracovat, ale byly na různých patrech), také o podpoře neformálního setkávání jako kuchyňky apod. Přímo ovlivňuje kvalitu inovativního prostředí.
  • Privacy – je o podpoře soukromí, míst, kde mám klid na to, co jsem v předchozím bodě vykomunikoval. V soukromí jsou lidé produktivnější. Důležité je podporovat i odchod ze soukromí zpět do "společnosti".
  • Permission – je o tom, co konkrétní prostory a firemní kultura objektivně umožňují, dává předchozím dvěma zásadám kontext, v rámci nějž je možné hledat řešení. Kontext je důležitý pro generaci Y a Z.
  • středověká knihovna - místo setkávání s druhými, výměny poznatků nebo kde si jen tak jedli a hráli
  • plus - kanceláře v blízkosti domova
Tento lightning talk řadím k lepším, téma rozvržení pracoviště je důležité a jeho vliv na produktivitu není dobré podceňovat. Mít několik let židli na stejném místě a přitom střídat projekty, je minimálně smell, který by měl vést k přehodnocení organizace práce. A to, jak se rozdělí lidi na pracoviště, pak v konečném důsledku může skrze Conwayův zákon ovlivnit i výsledný produkt.  🌟🌟🌟🌟

Karel Janeček – Demokracie 21 jako nástroj budoucnosti

  • prezentace "implementací" demokratického systému, přirovnání k číslům softwarových verzí
  • 1.0 = většinový systém US, UK
  • 1.2 = poměrný systém
  • 1.9 = pozitivní evoluce (taky nápad Karla Janečka, pikantní je, že doména pozitivnievoluce.cz je aktuálně přesměrovaná na https://news.d21.me/cs/)
  • princip Demokracie 2.1 (D21) = každý člověk má více hlasů než je vyhrávajících možností, tj. 1 prezident - 2 hlasy
  • příklad: 10 lidí různých národností hlasuje, do jaké jít restaurace. Každý hlasuje pro svoji kuchyni, ale protože jsou mezi nimi 2 Američané, získá McDonald 2 hlasy a zvítězí. V systému D21 by každý dal 2 hlasy a je pravděpodobné, že by zvítězila jiná, na které je větší konsenzus.
  • alternativa s jedním mínusovým hlasem - u příkladu s restaurací by mohla dokonce ukázat na to, že McDonald je nejméně chtěná varianta
  • kde D21 funguje - komunity (neziskové organizace, Tunisko), města (Říčany, New York City), byznys
  • občanská hra Prezident21 - prezident21.cz
  • zobecnění - sociologické hry K21 (království), P21 (party - oligarchický systém), H21
  • využití technologií - blockchain, anonymizace
Karel Janeček je matematik a z matematického pohledu mi myšlenka přijde taky zajímavá. Systém více možností není nic nového, např. v rodině ho běžně využíváme při plánování programu a umím si ho představit i do jiné menší struktury. Líbí se mi na něm i to, že nutí člověka nebýt spokojen jen s jednou možností (zpravidla tou, která odpovídá bublině, v níž žiju) a aspoň trochu se zajímat o alternativy.
Na druhou stranu zkušeností s tímto systémem je z mého pohledu co do množství i rozsahu pořád žalostně málo na to, abych chtěl zítra tímto směrem měnit Ústavu ČR. Jako u mnoha talků na Wisephoře i zde vnímám jako podceněnou, nedotaženou, nevyřešenou cestu mimo bublinu, v níž prezentátor žije. K voličům v úplně jiných sociálních sférách, neintelektuálům, nepolíbeným technologiemi, seniorům atd. To dost relativizuje radost ze 140k+ hlasujících na prezident21.cz i z průběžného první místa Jiřího Drahoše. Otevřená je i otázka, zda by nedostatky dosavadního systému nepřežily v modifikované podobě i do D21: neúčast ve volbách, odevzdání pouze jednoho hlasu, odevzdání druhého hlasu náhodně, jiný typ spekulací atd. To jsou vše oblasti, kvůli kterým mi D21 připadá jako experiment, jehož technická stránka zatím silně převažuje nad ostatními. 🌟🌟🌟

<tady jsem v červnu přestal přepisovat poznámky a dokončil to až v říjnu :-) >

Jiří FabiánJak se budí princezny

  • princezna = firma, spí = nevyužitý potenciál lidí, TopMonks příběh ("já jsem jenom zakladatel")
  • dávám lidem důvěru, citát Martina Paličky "kvůli 3% těch, co podvádí, nebudu kazit život zaváděním pravidel pro těch 97%"
  • masivně škálující uskupení, příklady z praxe: buurtz.org (organizuje desítky tisíc sester poskytujících domácí péči) nebo Morning star company (desítky tisíc zemědělců prodávajících přes ní rajčata)
  • naberete profesionály, ale nedovolíte jim být profesionály, pořád z toho děláte školku v podobě centrálního bottlenecku, který všechno ví
  • vize má mít 4 vlastnosti: hmatatelná (není to bullshit), dosažitelná (x chci být lepší než Facebook), inkluzivní  a epická (x chci udělat nejlepší sociální síť v Braníku)
  • firemní kultura = nejhorší chování tolerované managementem (Roman Staněk)
  • mikado technika - jít po dřívkách, udělejte graf závislostí
Jako topmonk mám maximální bias, ale potvrzuji, že co říká, to i žije, proto 🌟🌟🌟🌟🌟

Daniel Steigerwald

  • zmínka o ekonomech: Carl Menger, Ludwig von Mises, Friedrich August von Hayek a Murray Rothbard
  • ve firmách i rodinách taky dáváte přednost dohodě
  • hoaxokracie
  • v době anglické průmyslové revoluce se populace zdvojnásobila, děti přežily díky práci, jinak by zemřely
  • staytrix - už jsem zvyklý na to, že to tak je, že to nemůže být jinak
  • Když přišla babička (Boženy Němcové) na Staré Bělidlo, bylo jí 50, jako dnes Madoně.
  • spotřebitelé=šéfové
  • Ford: já nevyplácím platy,já jen přerozděluju, co dostanu za ty auta
I když jsem světonázorem jinde než přednášející, letos mi talk nepřišel tak militantní jako loni (možná i proto, že ke konci trochu nestíhal). Trefné bylo přirovnání současné babišovské politiky k 80. létům - návrat k vexláctví (paralela s bitcoinem), melouchaření a barteru jako reakce občanů na zbytečné státem házené klacky pod nohy. 🌟🌟🌟

Igor Tadić – Quick introduction to how we do innovations

Jak připravit děti na budoucnost ovlivněnou UI, idea kočovné školky (s omezením technických hraček za účelem testování talentu dítěte), univerzální učicí platformy. Povídání o Creative Docku. 🌟🌟

Matěj MichalkoPřekročení propasti blockchainových technologií

  • Decent - blockchainové platforma na digitální distribuci obsahu
  • očekává 5-10 let (od r.2016) do plné adopce (definované jako všichni budou vědět, co to je) blockchainu
  • popis adopce Gaussovou křivkou, prvních 16% early adopters, pak mezera, pak zbytek složený z early majority a late majority
Nezklamalo ani nezaujalo, zkrátka povídání o budoucnosti. 🌟🌟

Petr PouchlýJobcrafting jako dovednost pro 21. století

  • zaměstnanec x zatebestnanec = dělá práci za mě
  • pracovní role - přináším větší hodnotu než stojím
  • jobcrafting - nalezení své cesty/vize, plán cesty rozvoje, vím, kdo jsem a kam chci dojít (mohu říci že nevím, kam chci dojít, ale aspoň kterým směrem chci jít)
  • definovat význam pro byznys (čemu pomohlo dnešní posílání mailů)
Jedna ze zajímavějších přednášek. Kdybych měl krizi v práci nebo dělal v nesmyslné firmě, hledal bych zřejmě inspiraci u tohoto člověka. 🌟🌟🌟🌟

Petr KadlecMá smysl hledat smysl?

  • Knihy o štěstí nemají smysl. Tralé štěstí neexistuje, štěstí je jedna z emocí.
  • Viktor Frankl - dnešní člověk trpí propastným pocitem nesmyslnosti, s nímž spojuje pocit prázdnoty. (dejavú z poslední přednášky na Wisephora 2016)
  • mozek neustále balancuje mezi ohrožením a přínosem+odměnou
  • stav "musím" = nemám na výběr, nemám čas na věci,které bych chtěl dělat
  • stav "chci" = dělám, co mě baví, mám plnou volnost
  • smysl je to, co pomáhá překlopit "musím" na "chci"
  • když neznám smysl života, následuji vůdce (dělám, co ode mne žádá) anebo většinu (dělám, co dělají druzí)
  • cesta ke smyslu - liking (uspokojení) x wanting (naplnění)
  • liking = okamžité uspokojení, endorfiny, co dokážu od světa získat, krátkodobá, devalvuje po mnoha užitích
  • wanting = dlouhodobé naplnění, serotoninový systém, moje hodnota pro druhé, láska, radost, vztahy, co přináším, co umím, co znám, moje energie, pomoc, motivace ostatním
  • respekt x status
  • respekt = jaký jsem, co umím, čím přispívám
  • status = čím jsem a co vlastním 
  • náhražka - nejsme si jisti dostatečným respektem od ostatních
Petr Kadlec se zabývá výzkumem lidského mozku a na obsahu to bylo vidět. Laskavý talk, z nějž bylo vidět, že přednášející věří tomu, co říká, má to hlavu a patu a jako by shrnoval předchozí talky do obecných závěrů. Talk se setkal s kladným ohlasem a byla to důstojná final keynote. Po skončení bylo pro mne velmi příjemné si s přednášejícím popovídat osobně. 🌟🌟🌟🌟🌟

Závěr

Wisephoru 2017 hodnotím jako podařenou a rozhodně lepší než loni. I když určité bubliny podobných názorů byly stále patrné, pestrost, rozmanitost a přitažlivost osobností, jejichž přednášky tvořily obsah konference, to mnohem víc převážily. Velké přispění k příjemnému dojmu z konference mělo také moderování Jany Volencové, která byla takový Marek Eben v ženském provedení a dodávala programu flow a propojení. Díky ní i všem organizátorům z Topmonks!

7. 2. 2017

Playing with Java 8 collectors

I bet you wouldn't ever dare mutating key in HashMap. Such mutations lead to weird map behavior and hard-to-find bugs because of mismatch between actual hashcode and expected hash table bucket. In these blogpost I would like to talk about essentially same situation. Described problem has pretty bitten me in the ass and was not obvious at first sight due to nontrivial collector usage and improper usage of Guava BiMap.
As usually, I minimize problem scope and translate it to human-friendly domain.

Task

You are given set of activities and two sets of people representing work shifts. Each activity is assigned to just one person from first shift. At some time, all people from first shift have a rest and people from second shift start working. Each activity is reassigned to some person in second shift. The activity-to-person assignments are expressed as maps.

Your task is to list groups of activities which has been passed as complete set (i.e. not splitted nor merged) from one person to other.

For example, having Alice and Charlie in first shift, Bob, Dave and Ellen in second shift and following setup:

before\afterBobDaveEllen
Alicecleaning
cooking
Charliewashingironing

the result is set containing set [cleaning, cooking] since these activities were passed one-to-one from Alice to Bob, while Charlie splitted his work to two people.

Implementation note: generic types of data structures and collectors are complicated, often hard to read and sometimes enforcing usage of explicit type arguments. In order to avoid readers's confusion of map key and values, we will use just characters (java.lang.Character) A,B,C,D,E in following examples instead of full person names and reserve String type to modelling activities.

Incorrect implementation

The principle of solution is to "index" task assignment by person for both work shifts. Since I knew I would need to query both sides of association in practice, I chose to use Guava BiMap<Character,Set<String>>. Naive implementation would do following transformation of input Map<String,Character> into BiMap (get working example here):

BiMap<Character,Set<String>> index = activityToPersonMap.entrySet().stream()
        .collect(groupingBy(Map.Entry::getValue, HashBiMap::create, mapping(Map.Entry::getKey, toSet())));

The mapping(...) method creates the so called downstream collector - powerful mechanism of collector chaining, allowing to obtain Set<String> on the fly rather than Set<Map.Entry>. Also, since Guava BiMap is a Map we can provide factory method HashBiMap::create where supplier of a Map is expected.

After we got two BiMaps describing setup before and after, we just find sets of activities common to both BiMaps. Since the BiMap::values returns also Set, we just call

Sets.intersection(resultBefore.values(),resultAfter.values())

and we're done.

Really?

Let's run the example above:

Map<String,Character> before = ImmutableMap.of("cleaning",'A',"cooking",'A',"washing",'C',"ironing",'C');
Map<String,Character> after  = ImmutableMap.of("cleaning",'B',"cooking",'B',"washing",'D',"ironing",'E');
BiMap<Character,Set<String>> indexBefore = before.entrySet().stream()
        .collect(groupingBy(Map.Entry::getValue, HashBiMap::create, mapping(Map.Entry::getKey, toSet())));
BiMap<Character,Set<String>> indexAfter  = after.entrySet().stream()
        .collect(groupingBy(Map.Entry::getValue, HashBiMap::create, mapping(Map.Entry::getKey, toSet())));
System.out.println(Sets.intersection(resultBefore.values(), resultAfter.values()));

We expected [[cleaning, cooking]] but got []. Can you spot the bug?

Bug cause

BiMap keeps hashes also for inverse, value-to-key mappings. Hence for correct work of BiMap (unlike Map – where values can be safely mutated after putting into Map), values must not be mutated after they were put into Map. This limitation is crucial especially in this case where the value of BiMap is of Set<String> type.

In this wrong example, the toSet() method returns simple collector which creates Set and this set is added into newly created HashBiMap immediately after it was created. The value-to-key hash code is computed in early time for empty Set. Elements added later are physically stored into Set but hashcode is not recomputed and such a Set cannot be found – the HashBiMap is actually corrupted.

Correct implementation

Putting aside rewriting into plain old for-if imperative code (it should not be underpriced in practice, though I intentionally skip it for this article), the bugfix of functional implementation lies in deferring putting Set into BiMap to later time.

The accepted answer to very similar SO problem recommends using immutable sets. Let's try it:

BiMap<Character,ImmutableSet<String>> index = activityToPersonMap.entrySet().stream()
        .collect(groupingBy(Map.Entry::getValue, HashBiMap::create, mapping(Map.Entry::getKey, toImmutableSet())));

The ImmutableSet.toImmutableSet() method (you need Guava version 21+) returns collector which accumulates intermediate result into ImmutableSet.Builder. During stream processing, the builder is also stored into BiMap values though, so at first sight one could say this solution does not differ. However, (1) the builder does not override equals+hashCode, so its hashcode does not depend on its content, and (2) thanks to finisher associated with collector, the builder is converted to ImmutableSet at the end and replaced in BiMap.

We can prove correctness of such postponing even for mutable sets. The Collectors.collectingAndThen method wraps given collector and adds finisher after it. We wrap mapping collector and copy resulting value into new HashSet. The effect is same as in previous example.

BiMap<Character,Set<String>> index = activityToPersonMap.entrySet().stream()
        .collect(groupingBy(Map.Entry::getValue, HashBiMap::create, collectingAndThen(mapping(Map.Entry<String,Character>::getKey, toSet()), HashSet<String>::new)));

For completeness, creating Map first and then BiMap from Map would also be possible:

BiMap<Character,Set<String>> index = activityToPersonMap.entrySet().stream()
        .collect(collectingAndThen(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toSet())), HashBiMap::create));

You can try all examples in the gist.

Conclusion

The collector API is very powerful, although for more complex collector chains the timing of events during stream processing is not straightforward.
Collectors with finisher seem to be better comprehensible than simple collectors.
Also it's easy to encounter limits of Java compiler with respect to generic type inference.
After all, important cause of this bug was also in using BiMap constructor as Map supplier ignoring fact that BiMap violates Liskov substitution principle.