Kdy je programátor nejefektivnější?

Všiml jsem si na sobě jedné věci, která výrazně ovlivňuje mou efektivitu práce. V menší míře také chuť k práci. Bohužel ji neumím přesně pojmenovat, je to spíš mix různých věcí, ale věřím, že se mi jednou povede přijít s přesným pojmenováním. Nebo třeba někoho z vás. :-)

Nejpřesněji bych řekl zodpovědnost. Čím větší zodpovědnost mám, tím jsem efektivnější. Zkusím vysvětlit na několika případech.

Pracuji ve volném čase na vlastním projektu, kde řeším vše. Produkťáka, scrummastera, UXáka, front-endového i back-endového programátora, databázového specialistu, systémového administrátora, testera i uživatele. O projektu vím naprosto vše ze všech stran a svůj čas dělím mezi všechny role. Jaký to má dopad na výkon? Za jeden den dokážu naprogramovat tolik věcí, kolik by mi v práci, kde jsem pouze programátor, trvalo několik dní.

Jak je to možné? Jednoduše, při programování na svém projektu mám úplně vše v hlavě. Vše v jedné paměti, žádná latence synchronizace dat, žádné nedorozumění, jednoduše mám všechny možné informace postupovat mílovými kroky kupředu přes všechny překážky. Když v práci narazím na něco, co mi není jasné, potřebji se někoho zeptat. Takové záseky stojí spoustu času, nemluvě o tom, že ta správná osoba s odpovědí nemusí být po ruce. Ještě problemovější je, pokud programátor není seznámen s doménou projektu. Například u obchodní aplikace neznalost fungování obchodního či fakturačního oddělení má velký vliv na efektivitu.

Další příklad: v práci jsem vedl dlouho tým a dokázal jsem udělat neskutečné množství práce. Odmanažerovat, chodit na schůzky, vše sledovat a ještě vyřešit rekordní počet bugů či posunout projekt hodně kupředu. Pár lidí se mne ptalo, jak to dokážu, a já nikdy neměl odpověď. Už zřejmě mám – po pěti letech jsem znal aplikaci téměř celou, naučil jsem se řešenou doménu (obchod a fakturace) a byl jsem team leader, tedy také jsem věděl, co se děje a chystá na celé službě. To mi dalo téměř stejné možnosti jako doma na svém projektu. Při překážce jsem si dokázal odpovědět sám a věděl jsem, kdy si co mohu dovolit.

Vychází mi z toho, že abych byl efektivní, musím splnit následující body:

  • Naučit se doménu. Velmi dobře pochopit proč, jak a co dělám. To mi odstraní záseky, jak mám dané featury naprogramovat.
  • Sledovat co se děje na celé službě/projektu. To mi odstraní záseky při rozhodování, co je efektivní udělat dřív a co později.
  • Být full-stack developer. To mi odstraní záseky pří rozhraní dvou jazyků, typicky server a prohlížeč.
  • Získat důvěru. To mi odstraní záseky při rozhodování, jaké řešení zvolit.

Proto při přechodu do nového týmu nejprve pročtu všechny dostupné dokumentace, jak týmu, tak použitých technologií a knihoven. Prolezu poslední zápisy z retra a plánování. Naučím se zběžně, co se může hodit. Dokončit první úkol na dvě hodiny mi sice trvá třeba týden, ale naboostí mne to na všechny další.

A jak to máte vy, co vám pomáhá programovat efektivněji?

Ruby po vystřízlivění

Ruby mne hodně lákalo. Má několik zajímavých programátorských konceptů a syntaktických vychytávek, které se mi moc líbily a chtěl si je vyzkoušet. Vyzkoušel jsem si tedy Ruby pro jedno webové API a vyhnul se RoR, abych si vyzkoušel skutečné Ruby. Dopadlo to tak, že jsem si API po pár měsících přepsal do oblíbeného Pythonu.

Ruby má totiž opravdu spoustu vychytávek. Problém je, že jich má tolik, až není jasné, kdy bych měl kterou použít. Například se mi líbilo, že lze volat funkci různými způsoby, buď jako normální funkci, nebo jakoby kód funkce byl na místě volání. To pak otevírá možnosti zavolat třeba i předčasné ukončení „rodičovské“ funkce. Jenže pak je každé volání jiné a nikdy nevím, které použít. Je i několik způsobů na dědičnost, vyhazování výjimek, přístupu k atributům, podmínkování, vytváření polí, … a v různých knihovnách se využívají různé způsoby.

Což je problém. Sám jsem nevěděl, jaký přístup zvolit. Víc a víc jsem řešil, jak je která knihovna napsaná a jak bych si měl kód strukturovat. Navíc Ruby má podobný problém jako dřív JavaScript: Ruby on Rails je odpovědí na téměř jakoukoliv otázku. Což mne pak ještě více mátlo, protože jsem těžko rozpoznával, co je vlastně čisté Ruby, co built-in moduly, co third-party moduly a co RoR.

Na Ruby je vlastně krásně vidět problém, který je popisován v knize Coders at Work: Programátoři při psaní kódu chtějí přidat něco svého. Jenže je více věcí, které lze přidat, než věcí, které by se pouze měli přidat.

Zároveň s Ruby jsem na svém projektu použil i Haskell a ten jsem si naopak zamiloval. Je totiž Ruby přesným opakem, základ je velice jednoduchý. Začal jsem si tak více vážit věty z Pythoního modulu this: There should be one– and preferably only one –obvious way to do it.

Takže jsem si Ruby zkusil a tuto kapitolu uzavřel smazáním kódu. Jediné, co mi bude skutečně chybět, jsou vestavěné regulární výrazy.

Komentáře jsou nejdůležitější částí kódu

Už je tomu šest let, co jsem psal o hezkém kódu na Zdrojáku. Sice bych to dnes po zkušenostech na několika velkých projektech napsal lehce jinak, ale stejně je skvělé, jak jsem se sám tenkrát k něčemu takovému dostal a dokázal sdílet s ostatními. Každopádně – popisoval jsem, že komentáře je lepší nepsat. Pokud je nutkání napsat komentář, mnohem lepší varianta je upravit kód, aby byl samopopisný.

S tím stále souhlasím. Dostal jsem se však do bodu, kdy i když je kód popisný a hezký, komentář napíšu. To hned z několika důvodů. Ukážu na příkladech. První příklad budiž snippet z Flasku:

@app.before_request
def require_login():
    if is_user_logged_in():
        return

    if flask.request.endpoint == 'static':
        return

    view = get_current_view()
    if not view:
        return

    if is_view_public():
        return

    flask.abort(403)

Když přečtu za sebou, jak je, hned je zřejmé, co se děje. Volně přeloženo do češtiny: ověř přihlášení před zpracováním jakéhokoliv požadavku. Ale proč se to netýká statických souborů? Statické soubory nejsou chráněné? A vlastně – proč statické soubory řeší Flask a ne něco rychlejšího? Komentáře hned objasní…

@app.before_request
def require_login():
    if is_user_logged_in():
        return

    # Static files are not protected. Only in development without nginx.
    if flask.request.endpoint == 'static':
        return

    # Not found page is not protected.
    view = get_current_view()
    if not view:
        return

    if is_view_public(view):
        return

    flask.abort(403)

Pojďme na další ukázku z jednoho malého scriptu, který jsem nedávno psal:

def load_config_variable(key):
    variable = connection.configserver.variable.getAttributes(key)
    utc = dateutil.tz.tzoffset(None, 0)
    local = dateutil.tz.tzlocal()
    variable['since'] = variable['since'].replace(tzinfo=utc).astimezone(local)
    return variable

Opět je jasné, co se děje. Načítám proměnnou z konfiguračního serveru. Jenže, proč se tu přepočítává datum do jiné časové zóny? A proč zrovna do lokální a ne do jiné? Co se stane, když se změní čas z letního na zimní a obráceně?

#FIXME: Konexe ma spanou implementaci casovych zon. Z aware RPC datetimu prevadi
#       na naive Pythoni datetime (se ztratou informace o zone se zapocitanim
#       offsetu). Takze tu mame naive datum v UTC. Musime ho obohatit tedy o
#       zonu, aby slo do configserveru zpet zapsat.
#       Smazat jakmile se opravi prace se zonou v RPC.

Nyní už není pochyb, proč to tu je. Dokonce i co je potřeba udělat, aby bylo zase v pořádku.

Další ukázka z Reactu:

let EntryActions = {
    (...)
    reportProblem: function(id) {
        AppDispatcher.handleAction({
            actionType: RSSConstants.ENTRY_REPORT_PROBLEM,
            id: id,
        });
        EntryService.reportProblem(id);
    }
    (...)
};

Z úryvku je patrné, že se při odpálení akce z UI vyšle, že je s nějakým záznamem problém. To se pomocí service odešle na server. Ale co když se komunikace se serverem nezdaří? Na to tu nikde není žádný kód, to vypadá na chybu. S komentářem opět dodá informaci o úmyslu:

// Dve moznosti:
//  1) Jen na par tydnu, nez se vyladi zaznamy. Jelikoz se brzy smaze,
//     nema tedy smysl resit rollback v UI.
//  2) Nebo se bude ladit donekonecna, pak ale bude potreba i vyzadovat komentar,
//     aby se dobre zpracovavalo, a tudiz udelat jinak, tedy nema smysl resit rollback v UI.

Další příklad mohou být Jasmínové testy. Kolega napsal vše v pořádku, ale u jednoho describe měl pouze jeden it s prázdným popisem. Zdálo se mi to jako chyba. Přitom to měl promyšlené – struktura testů byla dle logických celků, ale jedna malá drobnost do toho ne úplně zapadala. Ale zachoval to, což bych při návštěvě kódu pravděpodobně změnil. Poprosil jsem ho tedy o komentář, jak zamýšlel strukturu testů, aby další kolemjdoucí dodržel.

Jinými slovy se snažím říct, že vy možná právě teď komentáře u čitelného kódu nepotřebujete. Komentáře s úmyslem jsou ale pro ostatní, včetně vás za pár měsíců či týdnů. Záleží jak dobře paměť slouží. Protože s takovými komentáři se lze vyhnout zbytečným chybám. Líbil se mi na toto téma tweet s následujícím gifem a popiskem „Why is this code here? We don't need this.“. :-)

Dokonce jsem zjistil, že mi pomáhá psát komentáře průběžně při vývoji všeho možného. Často sahám na spoustu míst a měním několik věcí najednou. Prototypuji. Rychle kód prasím. Až pak ho uhlazuji. Přijde mi to rychlejší než sáhodlouze přemýšlet, jak to udělat hezky na první dobrou. Proto si píšu komentáře, co se mi honí hlavou, a při uhlazování je postupně zpracovávám. Ve výsledku commitnu minimum napsaných komentářů, neb je proměnním v samopopisný kód a zůstanou jen ty komentáře vysvětlující úmysl.

A jelikož nejlepší komentář vysvětluje úmysl, přijde mi, že je častokrát důležitější, než kód samotný. Udělal jsem si takový malý průzkum a zjistil, že neexistuje žádný skin, kde by komentář nebyl téměř neviditelný. Proto jsem si sám ve všech používaných editorech nastavil komentáře tučně a křiklavě červené. Mám to tak přes měsíc a naprostá spokojenost.

Už jen škoda míst, kde nelze psát komentáře. Například v debianích souborech bych rád napsal, proč se například do deb balíku dávají i nějaké soubory a jiné naopak ne. Když to pak nejde, musí se napsat do dokumentace bokem. Jenže já mám tak rád, když se dokumentace generuje z kódu a nemusím na to myslet…

Na závěr taková perlička. Před dvěma lety jsem napsal takový ne zrovna hezký (asi tak jako samotný úkol), ale funkční, algoritmus na automatické generování práv v aplikaci. Napsal jsem k pár řádkům následující komentář (na který jsem úspěšně zapomněl) a kluci před pár dny našli:

# So you found a bug here. It's probably 2016. You know, it can't be
# fixed. You have to rewrite it completely. And what about your trip to
# Australia, was it good?

:-)

Nejlevnější letenka neznamená levnější dovolená

Nedávno jsem narazil na článek, jak hledat nejlevnější letenku. Já bych chtěl poukázat na to, že se honit za nejlepší letenkou nemá smysl. Ano, stále letenka bývá nejdražší položkou, ale…

…zaměnit destinace se ne vždy vyplatí. Například brzy vyrazím na dva týdny do Dominikánské republiky. Nedávno jsem viděl akci na letenky v mých termínech a mohl ušetřit až polovinu. To zní dobře, jenže to mělo drobný háček: musel bych se dopravit do Německa. Což by šlo zařídit, letenkou či autobusem. Stále bych ušetřil. Jenže pokud mne potká zpoždění, letadlo na mne nepočká a letecká společnost mi automaticky nezařídí první nejbližší možný let a odškodnění.

…znova opakuji, změnit destinace se ne vždy vyplatí. Akce popsaná výše nejenže byla z Německa, ale na jiné letiště v Dominikánské republice. Mám v plánu si Dominikánu projet, takže mám let do hlavního města, kde pobudu pár nocí, a teprve pak si půjčím auto. Alternativní letenka v akci by mě dopravila do malého města, kde bych si musel auto půjčit hned a v Santo Domingo by zbytečně draze stálo.

…čas je dražší. Levnější lety mívají často velký rozestup mezi lety, třeba osm hodin. Což pak znamená méně času na místě, kam se těším, neb počet dní na dovolenou je omezený. Přitom let s lepším přestupem není o tolik dražší. Spousta lidí říká, že se dá čas využít pro prozkoumání dalšího města. Jenže to mi zase nepřijde tak dlouho, aby se člověk řádně pokochal. Raději si to město projdu někdy jindy v klidu.

…znova opakuji, čas je dražší. Popravdě nemám moc čas hledat ty nejlepší letenky. Samozřejmě sleduji různé weby a čekám na (tu správnou) akci, ale když už jdu kupovat, většinou mám brzy hotovo. Řešit letenky několik dní a zkoušet různé kombinace mne nebaví. Mám spoustu jiných aktivit a těch pár stovek, které by šlo ještě víc ušetřit, se mi nevyplatí.

Tedy ano, dát si nějakou práci, používat anonymní okno, vyhýbat se víkendům, nakupovat v noci, ale jinak nepřehánět. Má to svou daň, která si to vybere v jiné podobě. :-)

Zápisky z cest: Španělsko

Olá amigos mučačos! Gr​á​cias. Adiós!

To je asi tak vše, co jsem se naučil při mém putování severním Španělskem. Ještě jsem se naučil například servéza, jenže já jsem spíš přes ty whisky. Uměl jsem chvíli taky frázi „jsme zemědělci“, aneb co průvodce nenaučí. Kolega uměl užitečnější „jsme softwaroví inženýři“, jenže v němčině. Naštěstí mají dvojjazyčné cedule. Španělsky a baskitsky.

Cestu po Španělsku jsem začal v Bilbau s kolegy na konferenci EuroPython. Bilbao je hezké město. Spousta zeleně. Spousta prapodivných budov. Spousta prapodivného čehosi. Skvělé místo na dělání abstraktních fotek.

Ale taky adrenalinové místo. Tedy pokud jste ve skupince programátorů, která se nechce škrábat do kopce na cestu a na druhou pláž jde raději, no, řekněmě „jinou cestou“. V žabkách.

Špinaví v rozbitých žabkách s modřinami jsme poté zašli do restaurace Extanobe s michelinskou hvězdou. Naprosto parádní zážitek! Rád bych vám sem dal fotky, ale nechtěli jsme udělat foajé (= nový alias pro faux pas jedné kamarádky) focením si jídla. Aby si nás nespletli s Instagram závisláky, kteří se do takové restaurace podívají jednou za uherský rok. Každopádně měl jsem zde zatím nejlepší steak a chobotničky. Zjistil jsem, že jídlo stále skrývá spoustu zajímavých chutí. Jen bych jim vynadal za nechání dobrého lokálního vína (Fefinanes 1583) na teple a že si jednou zkrátili cestu z levé strany. Což oboje napravili a věřím, že druhou hvězdu jednou získají.

Ono vůbec v baskitské oblasti vaří hodně dobře. Například v San Sebastianu je prý největší hustota michelinských restaurací na počet obyvatel. Samozřejmě ty nejlepší jsou vybookované hodně dopředu, takže doporučuji plánovat tak měsíc předem. Týden mi na žádnou z těch nejlepších nestačil.

Všudepřítomné pinchos a tapas se naštěstí bookovat nemusí a jsou skvělé. Dokud nejíte to samé celý týden, protože za boha nemůžete přijít na to, jak se tu jí. To bylo neustále „ještě nevaříme“ a vedle naopak „už nevaříme“. Nevěděli jsme, zda vědí, co říkají, či zda my víme, co říkají. Po několika dnech jsme se poradili s papírovým průvodcem (nojo, programátoři, návody se otevírají až v případě nouze) a zjistili, že všude měli pravdu. Jen na jejich dobu obědů a večeří jsme nebyli úplně zvyklí a měli hlad v jejich siestě.

Sem tam se dá narazit na turistickou restauraci, která respektuje čas hladu turisty. Ale věřte mi, ve Španělsku chcete jíst v jejich čas v restauracích pro Španěly. Tam je to dobré jídlo. Nikde jinde. Blivajzy můžete jíst doma. Mimochodem dávejte si zmrzlinu. Kdekoliv. Všude je skvělá. V Praze se musí chodit na pár správných míst (neprozradím!), ve Španělsku k nejbližšímu okénku se zmrzlinou. A v těch teplotách se hodí vždycky.

Ufff, to jsem se rozkecal o jídle, až jsem dostal hlad. Tak se podívejte zatím na fotky a zbytek dopíšu za chvíli.

To byla procházka San Sebastianem. Všimli jste si té pláže na poslední fotce? Prý je to jedna z nejlepších pláží v Evropě. Na to jsem měl pouze jednu reakci – chudák Evropa. Ale když jsem dojel k východnímu pobřeží, měl jsem jinou reakci – který, ehm, osel psal toho průvodce? V Sebastianu se jen pořádně najezte a vyrazte do Pyrenejí. Za prvé tam je děsně kýčovité městečko Torla, které se vám prostě zalíbí.

A hlavně hezké túry. Vypadá to jak z jižní Ameriky. Nebo odjinud, prostě ne z Evropy. Například jsem s kamarádkou šel jednu z těch nejvíce profláknutých cest, viz mapa. Jen jsme ji šli v opačném pořadí. Nejprve brzy ráno ten krpál a zbytek dne jsme se ploužili celým údolím nakonec k vodopádu a zpět z kopce. A je to tak lepší. Aspoň jsme stihli být nahoře brzy a užívat si pomalé osvětlování hor. A za parného dne se už nemuseli namáhat.

Pokud si chcete cestu přes Pyreneje prodloužit, stát v koloně, nedomluvit se, nenajíst se, nedělat vůbec nic, pak doporučuji navštívit Andorru. Měli jsme bezvadný nápad se tam jet podívat. Sice se nás autopůjčovna ptala, zda máme v plánu jet za hranice do Francie a my odpověděli ne. Ale za jiné hranice snad můžeme, to se nezmiňovalo a to drobné písmo ve Španělštině, kdo to má číst, že? Prostě jsme si udělali výlet. Můžeme si sice škrtnout další zemi, ale díky karmě jsem poznal hlavně jejich kolony a vše zavřené. Aspoň uprostřed (více méně) Andorry můžete vyjít na kopeček a podívat se kolem dokola… 

Ono obecně ve Španělsku jsou ty jejich otevírací hodiny nevyzpytatelné. Po příjezdu do Torly jsme viděli krámek. Chtěli jsme nakoupit jídlo, ale nejdřív hodit kufry na hotel. Než jsme se otočili, odbyla pátá a zůstalo zavřeno do konce dne. Druhý den naopak otevírali až v sedm večer. Nikde ani zmínka o otevíracích dobách. Poučen z dřívějška jsem tedy otevřel průvodce a tam… nic. Typické Španělsko!

Udělám si vlastního průvodce: koupat se chcete na východním pobřeží. Například v Tossa de Mar. Ale běžte se koupat pozdě večer, přes den tam je zbytečně moc lidí. V noci je voda stejně dobrá, navíc s výhledem na osvětlenou pevnost. Nebo brzy ráno, což bude krásně s východem. Před hotelem Rovira je pódium a když budete mít štěstí, bude tam nějaké vystoupení. Při mé návštěvě tam hrál živý orchestr super hity. Třeba skladby z muzikálu Bídníci, ale taky znělku ze Zorra, nedávný hit Happy od Pharella a spoustu dalšího.

Bodový Michalův průvodce po Barceloně:

  • Jak mi doporučil kolega, držte se v Barceloně Španělů, nikoliv turistů. Pokud nedokážete poznat Španěla, poznáte ho podle toho, že chodí ve stínu. Turista většinou ne.
  • Pokud není zrovna dostupný stín budov, jsou tu pro tyto odpolední případy všude možně stromy. Využijte je.
  • Metro není doporučená doprava po Barceloně. Možná ani nikde jinde ve Španělsku. Nemají ho dostatečně hluboko, takže tam je hůř, než venku. Přesný opak toho, co u nás.
  • Vedro je pouze ve stanicích, ve vagonech jede klimo o sto šest.
  • Pokud se rozhodnete jít pěšky, nemusíte se bát, že budete muset šlapat do kopce. Parky tu mají eskalátory. Něco takového jsem ještě nikde neviděl… ale tak proč ne, když už jsem je viděl do posilky, tohle mne nerozhází.
  • Ještě se tu jezdí hodně na skútrech. Jakože opravdu hodně. Takže je to možnost a půjčují je zde za cca 35 éček na den. Což teda není málo, ale lepší než tu drandit autem, s kterým se tu nezaparkuje.
  • Jíst je potřeba a o tom jsem už psal. Jen doplním možnost fastfood, který jsem prubnul až v Barceloně: ne. Prostě si zvykněte na místní režim. Turisti to nedělají a tak vlezou do fastfoodu, který jede jak jsme zvyklí. Zdejší fastfoody mají třeba tři patra na sezení a neskutečné fronty. A vůbec to jídlo za to nestojí.
  • Ale mají tam internet, to jo. Sice je po Barceloně Wi-Fi zdarma, ale ne vždy funguje. Takže když je potřeba se na něco podívat, je to jedna z možností. Každopádně s jídlem bych to nespojoval.

A zase u toho jídla. Jídlo mají skvělé, ale nemohl jsem si zvyknout na jejich hodiny ani po dvou týdnech. Měl jsem hlad stále ve svůj čas. A jak je chlap hladový… Navíc projet Barcelonu a najít místo, kde odevzdat auto, není vůbec snadné. Takže jsem byl dost vynervován. Chtěl jsem jít tedy relaxovat do parku Montjuïc. Napočítat si do pěti. Set. Ale bohužel, nejedná se o park jako park. Vedou v něm rušné silnice a je v něm spoustu hřišť a muzeí a tak.

Tak jsem zkusil centrum, aka rušnější a větší Václavák. Taky se spoustou kravin a komediantů, které se Španělskem nemají nic společného. Vzdálený Gaudího park Güell s výhledem na město je hezký, ale samotný výhled nikoliv. Praha se mi líbí víc. Začal jsem si říkat, že Barcelona za návštěvu nestojí. Ale pak jsem šel okouknout Picasovy obrazy a Gaudího budovy. Sám na umění moc nejsem, ale tyhle dva kluky doporučuji. 

Picasovi obrazy jsem si užil, především začátek muzea, neb mi přišlo, že v pozdějším věku už malování flákal. Jeho tvorba za mlada se mi líbila mnohem víc. Aneb jak začne být někdo slavný, změní ho to.

Gaudího jsem měl zaškatulkovaného jako „bláznivého architekta“ a popravdě se mi nechtělo moc jeho budovy prozkoumávat. Naštěstí jsem poctivý turista a jednu budovu si důkladně prošel, budovu Casa Batló. Pro mne bylo milé zjištění, že Gaudi nebyl vůbec bláznivý, ba naopak. Nejsou to pouze dizajnovky, ale vše má i prakticky promyšlené. Spoustu drobných detailů, které nejsou vlastně ani nijak sami o sobě zajímavé, ale že je vlastně použil a zkombinoval. A že to může celé vypadat zajímavě a hezky. Má ode mne palec hore.

Kdo mne zná, asi ví, že tancuji. Momentálně především salsu a bachatu. Samozřejmě když jsem, sakra, ve Španělsku, musím si užít i nějakou párty. Nevím co jsem komu udělal. Už jsem pochopil, že mi v šest večer nedají najíst. Ale že o půlnoci není na parketě ani noha, to už bylo na mne moc. V jednu sice zaplnili parket, jenže lidmi lákané na welcome drink. Navíc to tu brali spíš jako diskotéku a výzva k tanci nebyla přijata pěti ženami z pěti!

Tím jsem ukončil své putování a vrátil se ke svým oblíbeným kočkám do Prahy. Brzy zkusím přejít znovu na podobný režim stravování, ale tentokrát v Dominikáně. Tam by mohly mít ženy větší slabost pro Evropana a zatancují si se mnou. Případně to jistí můj záložní plán – rumová tour.

Adiós!

Používám ad-block

A nestydím se za to.

Ano, vím kde pracuji a co mne tedy živí. Nepoužívám ad-block primárně kvůli reklamě, ale především z technických důvodů. Čtu si pravidelně o bezpečnosti, prošla mi rukama také skvělá kniha Bulletproof SSL and TLS a mám zalepené kamerky. Možná jsem paranoidní. Nebo možná jen vím, jak to běžně v praxi chodí. A to tak, že bezpečnost řeší málokdo. Pokud ji už řeší, ne vždy ji řeší správně a důkladně. Ještě větší problém je, že ji občas nelze ani řešit důkladně, neb můžete narazit na JS plugin, který potřebujete, a musíte v CSP hlavičce kvůli němu povolit unsafe-eval.

Tedy existuje spousta webů se špatným zabezpečením a co se dostane do reklamní sítě, to se může jednoduše dostat ke spoustě lidem na spoustě webů. Což se už stalo nespočetkrát, třeba před pár dny Googlu. Samozřejmě bych mohl vytipovat důvěryhodné weby, jenže nikdy si nemohu být ničím jist.

Každopádně je tu další problém. Nechci být sledován. Teorie, kdy si web vydělává reklamou a tím může dodávat obsah zadarmo, je hezká, jenže prakticky reklama dělá na pozadí věci, které jsou u mne za čárou. Například Facebook se svým like tlačítkem na všech webech má přehled, kde se jeho uživatelé po webu pohybují (uBlock Origin má v 3rd-party filters sekci Social, doporučuji zapnout). Čte také soukromé zprávy a na jejich základě nabízí reklamy. Google zase čte e-maily. Je to logický krok a chápu ho; dobře zacílená reklama je lepší i pro uživatele.

Jenže se chci svobodně rozhodnout, komu dám důvěrné informace. Jestli vůbec někomu. Sice existuje „Do Not Track“ hlavička, jenže to je pouze dobrovolné. Spíš je to „prosím, nesledujte mě“. Což samozřejmě reklamní síť může a nemusí brát v úvahu. Či dokonce to ta síť může zahrnout do ještě lepšího sledování.

Navíc, jelikož nejsou weby ani na https, poskytovatelé internetu mohou přidávat do stránek reklamu, aniž by sami autoři takový počin schválili. Nemusí to být jen reklama, ale i malware.

Abych nezapomněl, žijeme v EU, kde každý web musí informovat o tom, že používá základní kámen webu. Cookies. Takže při návštěvě webu se musí nejprve odkliknout otravná hláška. Která se mimochodem taky s oblibou implementuje pomocí třetí strany, která tak dostává velkou moc být využita na šíření malware. (uBlock Origin má v 3rd-party filters EU: Prebake - Filter Obtrusive Cookie Notices, doporučuji zapnout.)

Sečteno podtrženo, dokud nebudu moct reklamním sítím či webům věřit, budu používat nekompromisně „ad-block“ na veškerou havěť. Obsah zadarmo neznamená, že musím otevřít dveře vandalům. Samozřejmě chápu vydavatele a nemám problém, aby mi zobrazili vstupní bránu, kde buď vypnu ad-block nebo zaplatím.

Checklist na zabezpečení webových aplikací

V poslední době jsem častokrát řešil bezpečnost webů a vzpomínal, cože vše to musím mít v cajku. Tak jsem se rozhodl si sepsat takový check-list. A možná bude užitečný i někomu jinému. :-)

Základem je HTTPS

Bez toho asi nemá smysl ani řešit nic jiného. Takže to je must-have první věc, kterou řešit, pokud chcete web zabezpečit. A ne jen nutně zabezpečit, cokoliv proběhne po drátech nešifrovaně, může kdekoliv po cestě někdo upravit. Třeba se na nás přiživovat vkládáním vlastní reklamy. Jop, i tací poskytovatelé internetu mezi námi existují.

HSTS

Když už je HTTPS nastavené, další krok je mít správně nastavený redirect z HTTP na HTTPS. Aby se nestalo, že lze nějak web prohlížet přes nezabezpečené vody. Když už jste si dali tu práci, ať to má smysl.

Redirect však není vše. Uživatelé často pečou na to, co do prohlížeče zadají, a tak útočník může vylákat oběť na HTTP, i když třeba máme redirecty pořešené. Proto nastavíme HSTS hlavičku, aby prohlížeč ani HTTP nezkoušel a v takovém případě sám přesměroval. (Ano, znamená to, že když podělám SSL, nebude vůbec fungovat web. Ale mnohdy lepší žádný, než nebezpečný.)

Strict-Transport-Security: max-age=31536000; includeSubDomains

Session cookie

Web je nyní zabezpečený a snažíme se našeho uživatele držet od HTTP co nejdále. Ale nikdy si nemůžeme být jisti, co se útočníkovi povede udělat. Proto budeme držet to nejcenější v co největším bezpečí. Mluvím o session v cookie. Rozhodně by měla být nastavena jako HTTP, což znamená, že ji nelze přečíst JavaScriptem. Mít nastaveno taky Secure není taky na škodu. Znamená to, že cookina půjde pouze po šifrovaném spojení.

CSP

Neboli Content Security Policy je hlavička povolující jen určité zdroje. To znamená, že touto hlavičkou lze znemožnit útočníkovi vložit nebezpečný script. Resp. vložit může, ale nic to neudělá. Lze nastavit defaultně pro všechny, případně pro každý typ zvlášť (obrázek, fonty, JavaScripty, …).

Rozhodně je dobré se vyhnout unsafe-inline či dokonce unsafe-eval. Nejlépe dovolit jen vaši doménu, případně ještě ověřené CDNky. A samozřejmě nejen zakázat, ale také zakázané pokusy nahlásit – je dobré vědět, zda se někdo o něco pokouší.

Content-Security-Policy: default-src 'self'; report-uri /csp-report;

Případně lze využít verzi, která jen nebezpečný zdroj napráší. Vhodné do začátku, než se odladí již běžící web, ale rychle bych se dostal do striktního módu.

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report;

XSS

CSP je fajn, ale pokud se útočníkovi povede dostat do stránky script přes naši samotnou webovou aplikaci, jsme namydlení. Naštěstí prohlížeče obsahují zabudovanou ochranu proti XSS (Cross Site Scripting). Normálně bývá zapnutá, ale jistota je jistota… (A opět lze bonzovat, což je asi to nejužitečnější na této hlavičce.)

X-Xss-Protection: 1; mode=block; report=/xss-report;

Iframe

Iframy se sice už nepoužívají, ale neměli bychom na ně zapomínat. Skrývají totiž potenciální nebezpečí. Útočník může naši stránku dát do iframe, překrýt nějakou zajímavou hrou (třeba klikací reklama v podobě „chytni všechny míče a máš možnost vyhrát nový iPhone“) a donutit tak uživatele kliknout na místa na našem webu, jak potřebuje. Proto je nejlepší úplně zablokovat možnost naši stránku v nějakém iframe mít.

X-Frame-Options: DENY

Typy souboru

Ať už na webu máme nahrávání souborů, které pak i zobrazujeme, či nikoliv, nikdy si nemůžeme být jisti, co se útočníkovi povede. Proto je možnost mu zase jednoduše znepříjemnit práci a to tak, že typ souboru budeme vždy určovat my a prohlížeč se nebude snažit hádat. Tedy pokud útočník nahraje JavaScript či celou HTML stránku, ale my takové věci nepodporujeme, pak prostě jako HTML stránku nevydáme a tudíž se nic nestane.

X-Content-Type-Options: nosniff

CSRF

Už jste si všimli, že e-mailové aplikace se ptají, zda zobrazit obrázky? Je to z důvodu, že pokud jste například přihlášeni na Facebooku a útočník vám poslal e-mail s obrázkem, který není obrázek, ale jen odkaz na smazání účtu, a vy se na takový obrázek chcete podívat… máte po účtu. Teoreticky. Bude to platit na webech, kde takové akce lze provést obyčejným GET požadavkem, což Facebook není.

Základem je veškeré akce nedělat GETem, ale POSTem či ostatními. To ale nezabrání místo obrázku využít například formulář, který uživatel vyplní nevědomky, neb si myslí, že je o něčem úplně jiném. Proto je dobré přidat ke každému požadavku ještě nějaký token. Na serveru vygenerovat token a ten při akci poslat zpět (a zvalidaovat, samozřejmě). Poté útočník musí nejprve zjistit i validní CSRF token, aby mohl takto uškodit. Což je podstatně složitější, neb web máme za SSL.

HPKP

Třešničkou na dortu je HPKP, což určuje, kterým certifikátům věřit. Defaultně prohlížeče věří všem certifikátům autorit, které mají v seznamu věrohodných. Jenže už se stalo, že byla certifikační autorita napadnuta…

Public-Key-Pins: pin-sha256='…'; pin-sha256='…'; max-age=5184000; report-uri=/hpkp-report;

V ukázce je vidět dvakrát pin-sha256. To není překlep, ale první je aktuálně používaný a druhý backup. Například příprava na vyexpirování atp. A opět lze zároveň bonzovat pokusy a nebo pouze bonzovat.

Public-Key-Pins-Report-Only: pin-sha256='…'; pin-sha256='…'; max-age=5184000; report-uri=/hpkp-report;

Hesla

Pokud se spravují hesla, musí se sledovat novinky a mít hesla co nejlépe zabezpečená. Tedy žádné MD5 hashe, ale co nejpomalejší hashovací algoritmus. Jakýkoliv algoritmus je oslaben proti jednomu typu útoku – brute force. Proto je dobré vybrat pomalý algoritmus, aby si nemohl útočník louskat hashe na jeho Raspberry po večerech. Často jsem používal PBKDF2 (default v Djangu), ale nic se nezkazí s bcrypt (náročné na CPU) či scrypt (náročné na paměť), které už jsou rozšířené. Mimochodem výkon lze stále lépe škálovat, než paměť.

Jelikož uniknutí databáze, kterou by mohl začít někdo louskat, nehrozí tak často, je potřeba se zamyslet taky nad přihlašovacím formulářem. Není dobré nechat útočníka v pohodě zkoušet louskat přímo na našem webu. Minimálně si monitorovat nebezpečné množství pokusů, raději s automatickým zpomalováním až blokováním. S blokováním však opatrně, neb se pak může zamezit přístup skutečným uživatelům. Například u naší „interní“ aplikaci víme, odkud se uživatelé přihlašují, takže můžeme podezřelá místa rovnou blokovat. U aplikací pro širokou veřejnost je lepší volbou zpomalování.

Logování

Pokud máte vše až potud, web máte dobře zabezpečen. :-) Ale dovolím si na závěr ještě jednu drobnost. A to, že i na druhé straně, tedy na vašem serveru, je potřeba k citlivým údajům přistupovat opatrně. Základem je mít vypnut debug mód v produkci (a nejlépe i na testu). I když má například Werkzeug debugger nově PIN k aktivaci, je to prostě díra.

Co je ale důležitější, je logování. Logujete si celé požadavky i se vstupními parametry? Všude, včetně login obrazovky? Pak máte logy pravděpodobně plné hesel v čitelné podobě. My jsme si například ve Flasku přetížili Werkzeugový ImmutableOrderedMultiDict, který skryje nebezpečné hodnoty.

Další tip, pokud pracujete v kódu často s citlivými údaji, použít nějaký speciální objekt, který nedovolí nijak zobrazit vnitřní hodnotu. Můžete pak hodnotu přenášet všude možně a máte jistotu, že se po cestě nezaloguje. Něco ve stylu:

class SecretValue(object):
    def __init__(self, secret_value):
        self.__secret_value = secret_value
    
    def get_secret_value(self):
        return self.__secret_value
    
    def __str__(self):
        return '--secret-value--'
    
    def __repr__(self):
        return '<SecretValue>'

>>> v = SecretValue('aaa')
>>> str(v)
'--secret-value--'
>>> repr(v)
'<SecretValue>'
>>> str({'value': v})
"{'value': }"
>>> logging.info(p)
INFO:root:--secret-value--
>>> logging.info('value: {}'.format(v))
INFO:root:value: --secret-value--

Poslední tip je na tracebacky. Python to například nedělá, ale PHP nahradí parametry funkcí za skutečné hodnoty. Docela užitečná věc pro debugování, ale nepraktická na citlivé údaje. Doporučuji takové chování vypnout, pokud lze. Pokud nelze, vybrat si rozumější nástroj. :-)


A to je vše! Aspoň z toho nejvíce důležitého. Pokud si myslíte, že mi něco ještě chybí, klidně mne upozorněte v komentářích.

Scrum není ztráta času

Občas mají vývojáři názor, že scrum stěžuje práci. Protože přináší s sebou spoustu schůzek a nemožnost změnit sprint. Místo aby umožnil vývojáři sedět u klávesnice a programovat. Že to je vlastně jen pro managery. To si osobně nemyslím a mám naopak zkušenost, že scrum chrání především nás, vývojáře. Rozhodl jsem se tedy sepsat, co mi scrum přináší.

Volnost.

Asi tímhle slovem bych celý přínos shrnul. Díky scrumu mohu přestat myslet na spoustu věcí a mám volnost v tom, do čeho se kdy pustím. Před scrumem totiž vývoj probíhal (u nás) tak, že byl dlouhý seznam všeho možného. Dlouhodobých i krátkodobých cílů, velkých i malých úkolů. Ve větším počtu lidí (řekněme dva a více) už začíná ztráta přehlednosti a je tedy těžké říct, kdy co může být hotové. To pak vedlo produkťáky k tomu, že když se změnila priorita (například když něco trvalo moc dlouho, raději se chtěli pustit do něčeho jiného; nebo jednoduše změnili názor), okamžitě nám diktovali, co máme dělat. Někdy i kdo.

Se scrumem naopak všichni víme (resp. vždy se můžeme podívat), co se právě dělá a co nás čeká v brzké době i jaké jsou dlouhodobější cíle. Produkťáci si udělají priority a na ty nejbližší se zaručí, že tak zůstanou. Na oplátku vývoj nejbližší úkoly ohodnotí a řekne, které určitě stihne během následujících dvou týdnů (prostě za sprint). Tím my, vývoj, víme, jaké priority jsou, a produkt ví, s čím může počítat. Radost na obou stranách bez diktatury, kdo co kdy má dělat.

Na tabuli pak visí spoustu úkolů a každý z týmu má možnost si práci vybrat a zorganizovat, jak mu vyhovuje. Žádný větší projekt bych už nechtěl dělat jinak. I na svém projektu, kde si sám sobě dělám i produkťáka, si řadím úkoly dle priorit a pak jako vývojář si beru dle aktuální chutě ty nejbližší.

Jako vedlejší účinek pak všichni mají možnost i vědět, co se děje na celém projektu. Což mi v případě vedení týmu zjednodušilo práci a v roli programátora ukonejší zvědavost a touhu pomoct v případě problému.

Samozřejmě nic není ideální a tak dalšími „zbytečným“ schůzkám jako retro můžeme proces dál zlepšovat. Scrum totiž není o tom dodržovat nějaké desatero. Je to o tom si to nastavit tak, aby co nejvíce vyhovovalo. A nejen zlepšovat proces vývoje, ale i samotný vývoj a komunikaci v týmu. Programátoři často žijí jen programováním, ale je potřeba budovat vztahy i kolem. S produkťáky, administrátory, obchodníky, … Lepší komunikace v týmu i mimo něj podstatně zpříjemní práci.

Mimochodem scrummaster je člověk, který se snaží sám sebe vyřadit z práce. Jeho cíl je, aby nebyl potřeba, aby tým fungoval jako hodinky i bez něj. Měl by nastavit vývoj tak, aby vše fungovalo, a pak jen dohlížet, zda tomu tak stále je. U nás platí, že jakmile scrummaster něco řeší, to něco nějakým způsobem drhne. Tedy na jedné straně sice scrum přidává meetingy, na druhé straně ubírá, neb přidává kvalifikovaného člověka, který řeší různé problémy kolem.

A to mi dává scrum. Chrání mne před neideální realitou požadavků. Samozřejmě není dokonalý a nic nebude, ale je to mnohem lepší, než bez něj. Pro mne určitě.

Zápisky z cest: Chorvatsko

Chorvatsko patří mezi místa, která mne nelákají navštívit. Asi proto, že tam jezdí všichni (krajané) a mám radši méně profláknutá místa. Každopádně jsem od kolegy dostal nabídku jet s ním a dalšími lidmi na týden plachtit. Úplně mi to nezapadalo do kalendáře, ale nakonec se vešlo. Přeci jen je to zážitek, který je třeba aspoň jednou zkusit. A určitě někdy pojedu rád znovu. :-)

Sice se při plachtění moc nepozná kultura, místní jídlo a tak, ale zase je to jiný zážitek, který zpestří jakým způsobem vyrazit do zahraničí. Navíc konkrétně Chorvatsko má příliš kamenité pláže se spoustou ježků. Minimálně jsem na jiné po dobu plavby nenarazil. Takže mít možnost si kdekoliv zakotvit a skákat rovnou do čisté vody… je prostě paráda.

Jelikož snad všichni v Chorvatsku bali, asi nemá smysl popisovat, že voda je opravdu bezvadně čistá. Jakože krásně čistá. Na mých cestách jsem lepší vodu zažil zatím pouze na Havaji, a to jen nepatrně lepší. Pro mne to bylo opravdu překvapením a pochopil jsem, proč sem tolik Čechů vlastně jezdí.

Ale méně kecání a pojďme se houpat! Houpání jsem se bál a ve výsledku mi pár dní potom chybělo. Spalo se jak v kočárku.

Samozřejmě jsme se také koupali. Například na otevřeném moři u Kornat, které šplhají nad i pod hladinu téměř ke stu metrům. To byla zatím největší hloubka, ve které jsem se koupal. A měl jsem z toho docela respekt!

Po vrácení se z otevřeného moře jsme narazili na opravdu nepříjemného chlapíka. Chtěl nám dovolit zůstat na bójce přes noc pouze pokud přijdeme do hospody na večeři. Všichni. Což samozřejmě nikde neměl napsané a nechal nás na bójce několik hodit se v klidu navečeřet. A peníze nechtěl. Dostal od nás přezdívku Hulk Hogan, neb tak skutečně vypadal.

Za trest z nás nedostal lautr nic. Místo hádání se s ním jsme podnikli noční cestu do zátoky v Landinu, kde se o nás naopak krásně postarali. Lucerničkou nám hezky posvítili na cestu k volné bójce. :-)

Brzy nám docházelo jídlo a tak jsme využili neuvěřitelné spoustě rybiček. Jen jsme hodili hrnec do vody a čekali, která bude mít smůlu… kecám. :-) Při házení zbytků do vody se vždy objevilo obrovské hejno ryb a všechny zbytky zlikvidovali během vteřinky. Ale ten hrnec jsme vážně zkusili. Bohužel asi věděli, k čemu je.

Rozhodli jsme se taky po ránu nakrmit, ale trochu jinak než rybičky. Tak, abychom lehce naštvali kolegy v práci. Nejprve jsme si řekli, že jen uděláme fotku s prázdnými skleničkami, jelikož stejně nebude moc poznat jejich (ne)obsah a tudíž bude stačit k provokaci. To se však kapitánovi nelíbilo (viz druhá fotka) a tak jsme skutečně pili od rána. Prostě správní námořníci. :-)

Po cestě jsme dobili jednu pevnost blízko Šibeniku, díky čemuž jsme si ji mohli celou prolézt skrz na skrz. Jen aby bylo jasno – dobití znamená připlout, vyložit posádku až na někoho, kdo musí zůstat a opustit molo pro další návštěvníky. A ten někdo by se měl pro svou posádku zase vrátit.

Loď jsme opouštěli i jindy, než jen pro průzkum pevnosti. Občas jsme vyběhli na pár minut pro čerstvé jídlo, zmrzliny atp. Druhý nejdelší pobyt na pevnině byl však v poslední večer v malebném městečku s bezvadnou restaurací. Popravdě je to už přes půl roku, takže si nejsem jist, zda restaurace byla skvělá díky jídlu nebo zábavnou vrchní. Myslím, že oboje bylo skvělé, i prostředí.

Což nechci říct, že dobré jídlo a zábava je pouze na pevnině. Na lodi jsme si jídla a zábavy užili habaděj. Ale jsou tam drzí racci, kteří úplně hypnotizují pohledem a nebojí se přiblížit opravdu blízko. Asi aby dobře viděli na hostinu a měli větší šanci ve správný moment něco uzobnout.

A na závěr několik kýčovitých fotek, protože západy mám prostě rád. :-)

Co mi dalo pět let na jednom projektu

Podobnost s předchozím článkem není ponechána náhodě. Je to takové volné pokračování myšlenek. Na interní službě SOS (Seznam Obchodní Systém) v rámci Seznamu jsem byl přesně pět let a jeden měsíc. Měsíc leden jsem tam zůstal navíc ještě jako podpora, kdy jsem hodně pároval a předával vědomosti nejen o projektu. To mi dalo i zajímavou příležitost vidět před odchodem celý projekt z trochu jiné perspektivy a čas na zamyšlení.

Díky tomu jsem si všiml jedné velmi zajímavé věci, které si lze všimnout právě po delší době na „jednom“ místě. Lidi se totiž točí přibližně co dva/tři roky a tak jsem poznal různé programátory a viděl jejich pohled na stejný kód a práci jejich předchůdců. A jelikož jsem znal i některé předchůdce, udělal jsem si obrázek.

Obrázek mi vyšel takový, že programátoři mají tendenci neustále něco zlepšovat. Aspoň to je to, co si myslí. Ve skutečnosti chtějí spíše měnit k obrazu svému. Jak si myslí, že je to správně. Realitou ale je, že nikdo neví, jak je to správně. I když víme, co vše systém má umět, nebudeme schopni si jít sednout a na zelené louce postavit krásnou vilku. Kód, který tam nyní je, by nebylo možné použít a nejlepší by bylo sáhnout po něčem novém. Novém Pyhtonu, jiné komunikační vrstvě, využít jiné patterny, napsat web jako SPA nebo naopak nepsat už jako SPA atd.

Tedy dnes sice víme, co jsme neměli dělat tak, jak jsme udělali. Jenže s dnešními technologiemi zase nevíme, čemu se vyhnout tentokrát. Protože to je prostě něco nového a musí se zase prozkoumat. Jinými slovy opět udělat chyby. Což je důležité si uvědomit, než se začne křičet jak někdo mohl něco napsat jak napsal.

Neříkám, že by se mělo smířit, jak kód vypadá, a přidat další bez žádného vylepšení. Právě přesný opak: zlepšovat! Ale ne neustále to samé. Protože mi přijde, že se často řeší ty samé věci dokola. A jakmile se dostane do jednoho bodu, začne se mluvit o tom, že to vlastně není dobře, a předělává se znovu. Třeba i do více méně verze, jak bylo dřív.

Byl jsem v tomhle ohledu mírný a dnes už vím, že bych měl přitvrdit. Například struktura kódu, validace vstupních dat, úroveň zobecňování, … jsou věci, které se řeší téměř všude a neustále, každý na to má svůj názor a jiné zkušenosti a nikdy řešení nebude perfektní. Protože perfektní neexistuje. Takže nemá smysl se snažit o dokonalost a neustále měnit ty samé věci.

Málokdo (čti opravdu málokdo, nejsem to ani já a velice pravděpodobně ani vy) dokáže napsat nadčasový kód. Podobně jako málokterý spisovatel dokáže napsat nadčasovou knihu či scénárista film.

Je potřeba se smířit s tím, že před námi napsal kód „prostě jen člověk“ a nezabývat se zbytečným přepisem. Na každém projektu je spoustu zajímavých a mnohem důležitějších oblastí, které je potřeba řešit. Stačí se rozhlédnout, udělat si seznam a priority. A řešit to, nikoliv jestli v pár let starém kódu je [doplň si jakoukoliv nekritickou věc, která tě irituje].