Author Archives: Lukáš Křečan

My AI experiments

These are just a few notes about my experiments with AI coding tools.

Key takeaways

  1. AI tools will indeed change the way we code. It’s a useful tool for some tasks, a distraction for others.
  2. To me, they are especially helpful for chores I don’t want to do. (learning and forgetting yet another YAML configuration format, writing boilerplate code, bash scripts etc.)
  3. AI is far from replacing engineers. It often gets stuck on trivial issues and then attempts random changes to fix the problem.
  4. AI usage leads to a lot of generated code. Without AI, my laziness pushes me to code reuse, abstraction and better design. AI can generate hundreds lines of code in a minute. My laziness pushes me to accept all the code, which can lead to a worse design.

All of the examples below are related to ShedLock, an OS project I am maintaining.

New Firestore provider

ShedLock can integrate with various DB technologies and from time to time I get a request to support a new exotic one. Recently I got a request to support Firestore. Usually I ask the requestor to send a PR. This time, I asked Junie to implement it. The process is pretty streamlined, the API is well defined, the structure of the code is similar between technologies, there is a test-suite that needs to pass, so this is an ideal task for AI.

Junie checked the structure of the project, implemented the code. Then I asked it to implement tests. Again, it found which class to extend to get the test suite, configured Firestore in testcontainers and almost did it all. But then it got stuck on a simple problem, it was configuring the test client using setHost("http://" + firestoreEmulator.getEmulatorEndpoint()). It’s kinda obvious that the host should not have the "http://" prefix, but not to the AI. It started to configure random environment variables, and do other random changes without solving the problem. But other than that, AI has been a huge time-saver. The implementation took like 15 minutes, you can see it here.

Fixing BOM

ShedLock provides BOM with a list of all modules. So every time, somebody adds a module, they should add it to the BOM. And surprise, surprise, people often forget. I wanted to check if there are some modules missing, but checking it manually is boring. You need to compare the list of modules with the BOM. Or you can ask your friendly AI and you are done.
Again, a huge time-saver. But what if you want to check the completeness in the build-time for each PR?

Checking BOM completeness

Let’s ask Claude “Is there a way (Maven plugin or something similar) to check that all modules are mentioned in BOM”. Claude goes directly for a bash script, trying to use xmllint. Which is not installed on my machine, I then try to steer it to use Java or Groovy, but at the end, it tried few approaches and it came up with a bash script like this . Does it work? Yes. Do I like it? No. Do I know a better way? No. And this is the tricky part. I have a working solution, which I don’t like. Maybe there is a better one. Maybe one of the solutions the model tried was the right one and did not work due to some trivial issue. I can continue prodding the AI to give me a better solution, and spend the whole day doing that.

For example, I can ask it to use Maven, it will praise my cleverness, and will spit out a Maven enforcer rule like this. Do I like it? Almost.

This is interesting. Without AI, I would have checked more thoroughly if there is no better way. If not, I would have abandoned the task as the value is not worth the effort. Or, I would have implemented the plugin, and shared it with others. But with AI, the effort to publish it is way bigger than the almost free implementation. So I will keep the plugin for myself. I am afraid we will see this more and more often. Instead of reusing tools and simple apps, we will generate tailor made ones. With AI it’s faster and easier to generate a simple tool than to search and evaluate existing ones.

Debugging flaky test

I had a flaky test. Time to time I got a few millisecond difference in one of the tests.

Error:    MsSqlExposedLockProviderIntegrationTest>AbstractJdbcLockProviderIntegrationTest.shouldCreateLockIfRecordAlreadyExists:81->AbstractLockProviderIntegrationTest.shouldCreateLock:49->AbstractJdbcLockProviderIntegrationTest.assertUnlocked:56 [is unlocked] 
Expecting actual:
  2025-06-19T16:01:23.840Z
to be before or equal to:
  2025-06-19T16:01:23.839Z

Here the AI failed completely. Event though, the issue was caused by a subtle bug in the code (the fix is here) Most of the models wanted to fix the test by add a buffer. And if I pointed that I suspect a bug in the code, this is what I got

Now I see the issue! The problem is that the Exposed provider is using LocalDateTime (datetime columns and CurrentDateTime) but the test is expecting timezone-aware timestamps.

Timezone issue causing a millisecond difference? Come on.

To be fair, the AI provided other plausible possible reasons for the issue, but it never guessed the right one. One of the models actually pointed to the line with the bug, but praised it for correctly handling MsSQL time rounding issues.

So to summarize, AI is a useful tool, if you are not already playing with it, pick a chore you are procrastinating on, and give it a try.

Za psaní kódu vás neplatí

Váš kód nikdo nechce. Nikdo nechce vaše skvělé internetové bankovnictví, nikdo nechce vaší aplikaci na telekonference, nikdo nechce vaše stránky na kupování letenek. Ano, lidi si chtějí kupovat věci, chtějí se povídat s vnoučaty, chtějí se dostat na druhý konec planety, ale kdyby to šlo bez počítačů, telefonů a všech těch internetů, byli by mnohem radši.

Proto vás neplatí za psaní kódu, ale za dodávání hodnoty. Dodávání. Hodnoty. Je to matoucí. Na pohovoru vás zkoušeli z psaní kódu, váš titul se jmenuje softwarový inženýr, lidi kolem se tváří, že po vás chtějí kód. No vidíte a oni po vás přitom nechtějí kód, ale dodávat hodnotu. Psaní kódu je samozřejmě nesmírně důležité, ale pokud ten kód nepřináší hodnotu nebo ho nejste schopni dodat včas a v potřebné kvalitě, tak je úplně zbytečný.

Proč to tu píšu? Protože si to lidé pořád neuvědomují. Slýchám jak Scrumové mítinky zdržují od práce (myšleno od kódování). Že je potřeba prodloužit sprint, aby bylo méně režie a více času na kódování. Mám chuť křičet, jak je to postavené na hlavu! Ano, kódování je nezbytné. Ano, je to to, co nás na naší práci baví. Ano, je to to, na čem jsem závislý. Ano, špatně zorganizovaná schůze jsou ztráta času. Naše práce ale není jen o psaní kódu.

Proč je důležité si to uvědomit? Zatímco psaní kódu nám jakž takž jde, v ostatních věcech kolem dodávání hodnoty jsme obvykle marní. Neumíme z rozsáhlého designu od designéra vyzobnout tu část, která přinese nejvíc hodnoty a s kterou je potřeba začít. Neumíme rozseknou story na menší, uchopitelnější. Neumíme si naplánovat sprint tak, abychom ho stihli. Neumíme zajistit kvalitu. Neumíme dodat MVP a získat zpětnou vazbu od zákazníka. Neumíme se zlepšovat a poučit z vlastních chyb. Neumíme odstranit překážky, které nám stojí v cestě k plynulejšímu dodávání.

Tohle všechno se musíme naučit což samosebou zabírá čas a energii. Navíc to není kódování, nechce se nám do toho. Nemohl by to dělat někdo jiný? Pamatuji časy, kdy se člověk mohl tvářit, že se ho to netýká. Na stůl přistála dokonalá analýza od týmu analytiků, tu člověk jen nakódoval, hodil to přes zeď testerům a o víc se nestaral. Ty časy jsou pryč. Hlavně proto, že to nefungovalo. Vývojáři o systému vědí nejvíc, bez nich se analýza dělá špatně. Testování se přesunulo do rukou automatů, to je zase kódování, to umíme líp než testeři. Ano, potřebujeme analytiky, designéry, QA a Operation lidi, ale nemůžeme se tvářit, že se nás jejich práce netýká.

Platí nás za dodávání hodnoty. Je potřeba se přestat tvářit, že každá minuta nestrávená psaním kódu je ztráta času. Ztrátou času je každá minuta, která nedodá zákazníkovi hodnotu nebo nás nenaučí, jak ji příště dodat lépe.

Mob programming

Posledních několik měsíců pracujeme s kolegy pomocí metody mob programming. V jednoduchosti jde o to, že celý tým pracuje u jednoho počítače, jeden píše, ostatní navigují. Funguje nám to úplně skvěle, měli byste to určitě také zkusit. Abych vám to trochu usnadnil, tak tu zkusím sepsat naše zkušenosti.

Výhody

Začnu výhodami. Ta nejzajímavější je pro mě ta, že odpadne většina ceremonií a koordinace. Celý tým pracuje pohromadě na jedné věci, nemusí se tedy koordinovat, dělat schůzky a navzájem se vyrušovat.

Představte si, že rozjíždíte nový projekt. Pokud pracujete klasicky, každý vývojář na vlastním písečku, tak je to celkem složité. Nejdřív musíte vymyslet a rozdělit úkoly pro jednotlivé vývojáře. Jarda bude zakládat strukturu projektu, Pepa bude studovat dokumentaci k externím systémům, Karolína bude chystat testovací prostředí. I když máte náhodou dost úkolů pro celý tým, tak se ti lidé musí neustále koordinovat. Věříte Jardovi, že strukturu projektu založí tak, že bude vyhovovat celému týmu? Co když to bude mít hotové a Karolína vymyslí lepší postup? Je zakládání testovací prostředí opravdu tak důležité, že se musí dělat hned, nebo to děláte jen proto, aby měli všichni co dělat? Jak Pepa předá znalosti dokumentace ostatním?

V mobu je to všechno mnohem snazší. Je nejdůležitější založit strukturu projektu? Všichni to dělají pohromadě. Dokončili jsme to? Všichni se vrhnout na něco jiného. Koordinace tam samozřejmě stejně probíhá, ale přirozeně, v průběhu práce. Vezměme například plánování. Právě jsme něco dokončili a nevíme co dál? Společně vybereme další nejdůležitější věc a vrhneme se na ní. Nemusíme řešit kdo umí co líp, kdo je na co specializovaný. Potřebujete retrospektivu? Není problém, uděláme ji hned. Není potřeba svolávat zvláštní meeting, všichni máme čas najednou. Zpočátku jsme tak třeba retrospektivu občas i několikrát denně a bylo to naprosto přirozené, jenom se tým přepl z módu programování do módu retrospektiva. Code review? Nemusíte na nikoho čekat nebo ho vyrušovat uprostřed rozdělané práce, všechno probíhá hned u každého napsaného řádku. Většina rozhodnutí probíhá okamžitě, čeká se jen na věci, které se z nějakého důvodu řeší mimo tým.

Další zjevná výhoda je kvalita kódu. V našem týmu jsme tři hodně zkušení vývojáři, každý z nás dokáže napsat slušný kód i samostatně. Ale ve třech je ten výsledek o hodně lepší. Když není jasné, jakou cestou se vydat, tak se to okamžitě probere, vybere se nejlepší řešení a jede se dál.

Vyšší kvalita výstupu z mobu u nás vynikne v porovnání s kódem, který vznikne při technických pátcích. V pátek si jednotlivě hrajeme s věcmi, na které není v průběhu týdne priorita. Kód který takto vzniká je prostě na první pohled horší než ten, který napíšeme společně. Dokonce i ten můj.

Je pravda, že kvalitu kódu by určitě zvedlo i párové programování. Ale už se nám několikrát stalo, že si někdo někam odběhl a zbytek pokračoval jen v páru. Po návratu nám ten třetí vymyslel fintu, která řešení výrazně vylepšila.

Třetí velká výhoda je učení se. Každý z nás je v něčem lepší. Když ostatní vidíte přímo při práci, tak se učíte mnohem rychleji. Od jednoho okoukáte finty při editaci, od druhého finty při psaní funkcionálního kódu, od třetího návyky při testování. O kódu diskutujete v podstatě pořád, takže se pořád učíte. A nejen kódování, poznáte jiné pohledy ne design, na to jak si kdo organizuje práci a podobně. Je to neuvěřitelně obohacující.

Na co si dát pozor

Samozřejmě to není všechno procházka růžovou zahradou. Hlavně ze začátku je to celkem náročné. Nebyli jsme zvyklí takto pracovat, takže nám to občas docela skřípalo.

Doporučil bych ze začátku přísně dodržovat pravidla. Řidič by měl poslušně dělat to co mu říká navigátor, neměl by se snažit dělat věci podle sebe. Měl by se chovat jako o trochu chytřejší klávesnice. Pro mě osobně bylo tohle hodně těžké. Jsem přeci zkušený programátor, proč by mě měl někdo navigovat. Je ale nesmírně důležité toto pravidlo dodržovat právě proto, abychom se naučili poslouchat co se nám ten druhý snaží říci. To je věc, kterou (nejen) v mobu potřebujete neustále.

Navigátor by se měl svědomitě snažit určit míru potřeby navigace. Je to podobné jako v autě. Zkušenému řidiči stačí oznámit, že má jet do Brna a pak se jen vézt. Pokud řidič neví kde je, musíte mu radit každé odbočení. A pokud je to řidič začátečník, je potřeba mu radit i to, jaký stupeň má zařadit. S navigováním v mobu je to podobné. Chvíli trvá naučit se poznat, co kdo v daný okamžik potřebuje. I řidič se musí naučit dát vědět, jestli je ztracený nebo jestli je mu všechno jasné, jestli potřebuje vodit za ručičku nebo jestli mu jen stačí naznačit směr.

A pokud zrovna neřídíte ani nenavigujete, musíte se naučit odlišit situace kdy je potřeba mlčet a kdy do toho začít navigátorovi kecat.

Nám se osvědčil časovač, který nás nutil se pravidelně po čtyřech minutách střídat a časté retrospektivy, kdy jsme si vyříkali, co fungovalo a nefungovalo. Časem jsme pravidla postupně opouštěli a nic se nestalo. Věřím ale, že jen dodržování pravidel nám umožnilo naučit se vnímat potřeby ostatní.

Jeden důvod, proč nám to občas skřípalo byla nejasnost zadání. Když si řidič myslí, že jedeme co nejrychleji do Brna a navigátor, že je nutné co nejdřív někde nabrat benzín bez ohledu na zajížďku, tak pak oba nechápou, co ten druhý blbne. Nám pomáhá rozpadnou si story na malé kroky a ukázat si, že teď děláme tohle. Časem jsme se naučili se i zastavit a zeptat se co se děje a nepovažovat toho druhého rovnou za pomateného.

Umět se zeptat toho druhého, proč dělá něco nepochopitelného je důležitá schopnost, bez které se v mobu neobejdete. A opět nejen v mobu.

To mě vede k další nevýhodě mobu. Je to celkem psychicky náročné. Hlavně proto, že kromě kódu musíte vnímat i lidi kolem sebe. Najednou to není jenom o tom, že jsem ponořený v problému, musím si všímat i těch divných bytostí co na mě pořád mluví. Celkem nezvyk. Je proto důležité si pravidelně dělat přestávky, aby měl člověk čas dobít baterky.

Další věc, která mě při mobování překvapila je to, jak jsem závislý na počítači. Jak moc si nepamatuju jména základních tříd, jak moc často potřebuju googlovat. Když navigujete, tak si připadáte jako bez rukou. Chcete řidiči říci, že má použít třídu XYZ, ale nepamatujete si její název. Po čase mě to přešlo, ale ze začátku je to docela síla. Časem se naučíte přiznat si, že nevíte a říci řidiči, že si to má vygooglovat sám.

Co nám nejde dodnes je dubugování. Při hledání chyb potřebujete rychle zkoušet hypotézy a vyvracet nedopečené nápady. To jsme se zatím v konfiguraci řidič/navigátor nenaučili. Dáváme buď víc prostoru řidičovi nebo se každý rozejde na vlastní počítač. Na druhou stranu opravdu záludnou debugovací situaci jsme měli zatím jen dvakrát, v mobu je výrazně větší šance, že si chyby někdo rychle všimne.

Nečekaně dobře nám mob funguje v době koronaviru. Jedeme vzdáleně, sdílíme obrazovku, při střídání pushujeme do Gitu, což zabere pár sekund. Naopak, pokud se někdo potřebuje postarat o děti nebo podlít maso, tak jen odběhne a tým jede dál. Nevím ovšem, jak by nám to vzdáleně fungovalo, kdybychom si na sebe ještě vzájemně zvykali.

Dnes jsme ve fázi, kdy pravidla už moc nedodržujeme, střídáme se když se to hodí, navigují všichni co zrovna neřídí a tak nějak tušíme, jak by danou situaci řešil, který člen týmu. Já vím, že se kluci vyhýbají ifu jak čert kříži, kluci vědí, že nerad používám data classy tam kde nemají být. Občas nám to skřípe, občas si nerozumíme, ale většinu doby máme pocit, že dohromady odvedeme víc kvalitnější práce než by to dokázal každý zvlášť. Takže se nebojte to zkusit. Je to zábava a naučíte se hrozně moc.